vieja pregunta, pero añadiendo una respuesta descriptiva, ya que creo que sería útil para un nuevo desarrollador.
También probé con self
. base_fields
, pero no tiene efecto: siempre se visualiza el valor de la base de datos en el formulario. ¿Algunas ideas?
Si un formulario se "inicializa" forma, ya sea: -
usando initial
argumento (. Ej YourModelFrom(initial={'filed1': variable})
— generalmente el caso, cuando se quiere pasar valores iniciales calculados dinámicamente para algunos campos) . Referencia Setting Initial Values
o
usando instance
argumento (por ejemplo. YourModelFrom(instance=model_object)
— suele ser el caso, cuando se quiere actualizar un objeto instancia de modelo existente). Referencias más de ModelFrom save() method
Nota:
clase hereda `BaseModelFrom` clase. La clase `BaseModelFrom` hereda la clase `BaseForm`.
2 El argumento instance
se añade en `BaseModelFrom` constructor de la clase, cuando asignamos un objeto de modelo de instancia de clase a instance
argumento (de ahí instance is not None
) entonces `BaseModelFrom` constructor llama model_to_dict()
y actualizaciones initial
argumento antes de llamar a super constructor de clase. Compruebe def __init__
en clase BaseModelFrom
A continuación, asignar un valor inicial a un campo de forma explícita (como se muestra en el código de OP en cuestión) no efecto, esto es debido a la forma _clean_fields
método está escrito en BaseFrom
clase.
Código Snip:
def _clean_fields(self):
for name, field in self.fields.items():
value = field.widget.value_from_datadict(
self.data, self.files, self.add_prefix(name))
try:
if isinstance(field, FileField):
initial = self.initial.get(name, field.initial) # <- Check
value = field.clean(value, initial)
else:
De acuerdo con la línea de código initial = self.initial.get(name, field.initial)
, si el valor inicial para el campo se da en initial
dict entonces el valor asignado a field.initial
es no utilizado.
[RESPUESTA]:
Aunque, @ Daniel respuesta es perfectamente correcto, pero uno puede también como otra manera de lograr mismo efecto es el uso de self.initial
:
def __init__(self, *args, **kwargs):
super(ArtefactForm, self).__init__(*args, **kwargs)
self.initial['material'] = 'Test'
darle una oportunidad !!
self.initial
no es más que el dict que pasamos en discusión. Verificar código __init__
en BaseForm
:
class BaseForm(object):
def __init__(........
........):
:
self.prefix = prefix
self.initial = initial or {} # <-- Notice
self.error_class = error_class
:
Nota: No he encontrado ninguna documentación relacionada con el uso del atributo inicial, sólo exploró el código base y la utilicé.
Editar: el comportamiento reportado en cuestión también se documenta en Django Modelo
Form.initial
Tenga en cuenta que si un Field
define initial
y que incluyen initial
cuando instancia el formulario, entonces el último initial
tendrá prioridad. En este ejemplo, initial
se proporciona tanto a nivel de terreno y en el nivel de instancia de formulario, y este último obtiene precedencia:
>>> from django import forms
>>> class CommentForm(forms.Form):
... name = forms.CharField(initial='class')
... url = forms.URLField()
... comment = forms.CharField()
>>> f = CommentForm(initial={'name': 'instance'}, auto_id=False)
>>> print(f)
<tr><th>Name:</th><td><input type="text" name="name" value="instance" />
<tr><th>Url:</th><td><input type="url" name="url" /></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
PD: Por cierto, el punto 2, en mis respuestas diga diferencia entre initial
y instance
argumento. Su es un argumento de valor-clave más data
- los valores en eso activan las validaciones de formulario. lea esto Difference between Django Form 'initial' and 'bound data'?.
perfecto, gracias. – schneck