Django imposta i valori predefiniti del modulo


241

Ho un modello come segue:

class TankJournal(models.Model):
    user = models.ForeignKey(User)
    tank = models.ForeignKey(TankProfile)
    ts = models.IntegerField(max_length=15)
    title = models.CharField(max_length=50)
    body = models.TextField()

Ho anche un modulo per il modello sopra come segue:

class JournalForm(ModelForm):
    tank = forms.IntegerField(widget=forms.HiddenInput()) 

    class Meta:
        model = TankJournal
        exclude = ('user','ts')

Voglio sapere come impostare il valore predefinito per quel campo nascosto del serbatoio. Ecco la mia funzione per mostrare / salvare il modulo finora:

def addJournal(request, id=0):
    if not request.user.is_authenticated():
        return HttpResponseRedirect('/')

    # checking if they own the tank
    from django.contrib.auth.models import User
    user = User.objects.get(pk=request.session['id'])

    if request.method == 'POST':
        form = JournalForm(request.POST)
        if form.is_valid():
            obj = form.save(commit=False)

            # setting the user and ts
            from time import time
            obj.ts = int(time())
            obj.user = user

            obj.tank = TankProfile.objects.get(pk=form.cleaned_data['tank_id'])

            # saving the test
            obj.save()

    else:
        form = JournalForm()

    try:
        tank = TankProfile.objects.get(user=user, id=id)
    except TankProfile.DoesNotExist:
        return HttpResponseRedirect('/error/')

Risposte:


402

Puoi usare l' iniziale che è spiegato qui

Sono disponibili due opzioni per popolare il valore quando si chiama il costruttore del modulo:

form = JournalForm(initial={'tank': 123})

o imposta il valore nella definizione del modulo:

tank = forms.IntegerField(widget=forms.HiddenInput(), initial=123) 

E come viene initialpassata quella variabile al modulo effettivo? Nel modello di modulo attuale, dobbiamo scrivere come parametro / argomento?
mgPePe

2
@bharal È magico. ;-) (O meglio, i costruttori di forme Django comprendono la speciale variabile "iniziale" e passano in rassegna i suoi contenuti senza che tu debba fare nulla in più). Personalmente, preferisco specificare i valori predefiniti nella definizione del modulo e utilizzare il meccanismo iniziale = ... solo se il valore predefinito desiderato è un valore dinamico (ad esempio qualcosa immesso da un utente o basato sul suo accesso, posizione geografica, ecc.)
Richard J Foster,

66
iniziale non è predefinita. Il valore iniziale non si applica se il modulo è stato associato :(.
clime

4
Commentando qui per menzionare un altro caso d'uso in cui questa soluzione di param iniziale aiuterà: Durante l'invio di un collegamento di registrazione a qualcuno se si desidera prepopolare l'e-mail / ID o qualsiasi altra credenziale nel modulo di registrazione, in tal caso non è possibile scrivere in il modello stesso come dinamico piuttosto è necessario chiamare il costruttore con il parametro iniziale come indicato da @ umnik700. Funziona alla grande!
Keshav Agrawal,

1
@Phlip: non sovrascrivere View.get_formper impostare i dati iniziali. Qualsiasi CBV con FormMixin (sostanzialmente tutti i CBV che creano o modificano i dati) può utilizzare una initialvariabile di livello di classe (per valori di default invariati) oppure è possibile eseguire FormMixin.get_initial()l' override per restituire un dettato di valori iniziali da passare al costruttore del modulo (per valori di default dinamici .)
GDorn,

29

Altra soluzione: impostare iniziale dopo aver creato il modulo:

form.fields['tank'].initial = 123

Questo lavoro per il mio bisogno, inizia solo un campo nel modulo. grazie.
bl4ckb1


11

Ho avuto quest'altra soluzione (la sto pubblicando nel caso qualcun altro come me stia usando il seguente metodo dal modello):

class onlyUserIsActiveField(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(onlyUserIsActiveField, self).__init__(*args, **kwargs)
        self.fields['is_active'].initial = False

    class Meta:
        model = User
        fields = ['is_active']
        labels = {'is_active': 'Is Active'}
        widgets = {
            'is_active': forms.CheckboxInput( attrs={
                            'class':          'form-control bootstrap-switch',
                            'data-size':      'mini',
                            'data-on-color':  'success',
                            'data-on-text':   'Active',
                            'data-off-color': 'danger',
                            'data-off-text':  'Inactive',
                            'name':           'is_active',

            })
        }

La funzione iniziale è definita __init__comeself.fields['is_active'].initial = False


0

Spero che ciò possa aiutarti:

form.instance.updatedby = form.cleaned_data['updatedby'] = request.user.id

0

Come spiegato nei documenti Django , initialnon lo è default.

  • Il valore iniziale di un campo deve essere visualizzato in un HTML. Ma se l'utente elimina questo valore e infine restituisce un valore vuoto per questo campo, il initialvalore viene perso. Quindi non si ottiene ciò che è previsto da un comportamento predefinito .

  • Il comportamento predefinito è: il valore che il processo di convalida prenderà se l' dataargomento non contiene alcun valore per il campo.

Per implementarlo, un modo semplice è quello di combinare initiale clean_<field>():

class JournalForm(ModelForm):
    tank = forms.IntegerField(widget=forms.HiddenInput(), initial=123) 

    (...)

    def clean_tank(self):
        if not self['tank'].html_name in self.data:
            return self.fields['tank'].initial
        return self.cleaned_data['tank']
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.