vecchia questione, ma l'aggiunta di una risposta descrittiva come credo che sarebbe utile per qualche nuovo sviluppatore.
Ho anche provato con self
. base_fields
, ma nessun effetto: c'è sempre il valore del database visualizzato nel modulo. Qualche idea?
Se un modulo è "inizializzato" forma, sia: -
utilizzando initial
argomento (es. YourModelFrom(initial={'filed1': variable})
— generalmente il caso, quando si vuole passare i valori iniziali calcolati in modo dinamico per alcuni campi) . Riferimento Setting Initial Values
o
utilizzando instance
argomento (ad es. YourModelFrom(instance=model_object)
— solitamente il caso, quando si vuole aggiornare un oggetto esistente un'istanza del modello). Riferimenti leggono di ModelFrom save() method
Nota:
classe eredita `BaseModelFrom` classe. La classe `BaseModelFrom` eredita la classe `BaseForm`.
2 L'argomento instance
viene aggiunto in `BaseModelFrom` costruttore della classe, quando si assegna un oggetto del modello un'istanza classe instance
argomento (quindi instance is not None
) allora `BaseModelFrom` costruzione chiama model_to_dict()
e aggiornamenti initial
argomento prima chiamare costruttore della super-classe. Controllare def __init__
in classe BaseModelFrom
assegnando valore iniziale di un campo in modo esplicito (come mostrato nel codice di OP in questione) non effetto, questo è dovuto al modo in cui _clean_fields
metodo è scritto in BaseFrom
classe.
Codice 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:
Secondo riga di codice initial = self.initial.get(name, field.initial)
, se il valore iniziale per il campo è dato in initial
dict quindi valore assegnato a field.initial
è non utilizzato.
[RISPOSTA]:
Anche se, @ Daniel risposta è perfettamente corretto, ma si può anche come un altro modo per ottenere lo stesso effetto utilizza la self.initial
:
def __init__(self, *args, **kwargs):
super(ArtefactForm, self).__init__(*args, **kwargs)
self.initial['material'] = 'Test'
dargli una prova !!
self.initial
non è nient'altro che è il contrario. Controllare il codice __init__
in BaseForm
:
class BaseForm(object):
def __init__(........
........):
:
self.prefix = prefix
self.initial = initial or {} # <-- Notice
self.error_class = error_class
:
Nota: Non ho trovato alcuna documentazione relativa a utilizzare l'attributo iniziale, ho appena esplorato il codice di base e l'ho usato.
Edit: il comportamento riportato in questione è anche documentato in Django Modello
Form.initial
Si noti che se un Field
definisce initial
e si includono initial
quando istanziare il modulo, quindi il secondo initial
avrà la precedenza. In questo esempio, initial
viene fornito sia a livello di campo e al livello di istanza modulo, e il secondo ottiene la precedenza:
>>> 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>
PS: A proposito, il punto 2 nelle mie risposte dicono differenza tra initial
e argomento instance
. Il loro è un altro argomento chiave-valore data
- i valori in tali trigger formano convalide. leggi questo Difference between Django Form 'initial' and 'bound data'?.
perfetto, grazie. – schneck