Nuestros mejores programadores agotaron sus provisiones de café, investigando diariamente por la solución, hasta que Alex halló la contestación en GitLab y en este momento la compartimos con nosotros.
Solución:
Como se señaló en esta respuesta, Django 1.9 agregó Field.disabled attribute:
El argumento booleano deshabilitado, cuando se establece en Verdadero, deshabilita un campo de formulario usando el HTML deshabilitado attribute para que los usuarios no puedan editarlo. Incluso si un usuario manipula el valor del campo enviado al servidor, se ignorará a favor del valor de los datos iniciales del formulario.
Con Django 1.8 y versiones anteriores, para deshabilitar la entrada en el widget y evitar hacks POST maliciosos, debe eliminar la entrada además de configurar el readonly
attribute en el campo del formulario:
class ItemForm(ModelForm):
def __init__(self, *args, **kwargs):
super(ItemForm, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
if instance and instance.pk:
self.fields['sku'].widget.attrs['readonly'] = True
def clean_sku(self):
instance = getattr(self, 'instance', None)
if instance and instance.pk:
return instance.sku
else:
return self.cleaned_data['sku']
O reemplazar if instance and instance.pk
con otra condición que indica que está editando. También puede configurar el attribute disabled
en el campo de entrada, en lugar de readonly
.
El clean_sku
La función asegurará que el readonly
el valor no será anulado por un POST
.
De lo contrario, no hay un campo de formulario Django integrado que genere un valor mientras rechaza los datos de entrada vinculados. Si esto es lo que desea, debería crear un ModelForm
que excluye los campos no editables y simplemente imprímalos dentro de su plantilla.
Django 1.9 agregó Field.disabled attribute: https://docs.djangoproject.com/en/stable/ref/forms/fields/#disabled
El argumento booleano deshabilitado, cuando se establece en Verdadero, deshabilita un campo de formulario usando el HTML deshabilitado attribute para que los usuarios no puedan editarlo. Incluso si un usuario manipula el valor del campo enviado al servidor, se ignorará a favor del valor de los datos iniciales del formulario.
Ajuste readonly
en un widget solo hace que la entrada en el navegador sea de solo lectura. Añadiendo un clean_sku
que regresa instance.sku
asegura que el valor del campo no cambiará en el nivel del formulario.
def clean_sku(self):
if self.instance:
return self.instance.sku
else:
return self.fields['sku']
De esta manera, puede usar el modelo (guardado sin modificar) y evitar obtener el error de campo requerido.