Django menetapkan nilai formulir default


241

Saya memiliki Model sebagai berikut:

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()

Saya juga memiliki formulir model untuk model di atas sebagai berikut:

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

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

Saya ingin tahu cara mengatur nilai default untuk bidang tersembunyi tangki itu. Inilah fungsi saya untuk menunjukkan / menyimpan formulir sejauh ini:

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/')

Jawaban:


402

Anda dapat menggunakan inisial yang dijelaskan di sini

Anda memiliki dua opsi untuk mengisi nilai saat memanggil konstruktor formulir:

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

atau atur nilai dalam definisi bentuk:

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

Dan bagaimana variabel itu initialditeruskan ke bentuk aktual? Dalam model formulir yang sebenarnya, apakah kita harus menulis sebagai parameter / argumen?
mgPePe

2
@harhar Ini ajaib. ;-) (Atau lebih tepatnya, Django form constructor memahami variabel "awal" khusus dan beralih melalui isinya tanpa Anda perlu melakukan sesuatu yang ekstra). Secara pribadi, saya lebih suka menentukan nilai default dalam definisi bentuk dan hanya menggunakan mekanisme awal = ... jika default yang diinginkan adalah nilai dinamis (misalnya sesuatu yang dimasukkan oleh pengguna, atau berdasarkan login, lokasi geografis, dll.)
Richard J Foster

66
inisial tidak default. Nilai awal tidak berlaku jika formulir telah terikat :(.
clime

4
Mengomentari di sini untuk menyebutkan usecase lain di mana solusi param awal ini akan membantu: Saat mengirim tautan pendaftaran kepada seseorang jika Anda ingin mengisi ulang email / id atau kredensial lain pada formulir pendaftaran maka dalam hal ini Anda tidak dapat menulisnya di model itu sendiri sebagai dinamiknya bukan Anda perlu memanggil konstruktor dengan param awal seperti yang disebutkan oleh @ umnik700. Bagus sekali!
Keshav Agrawal

1
@ Unggl: Jangan mengganti View.get_formuntuk mengatur data awal. CBV apa pun dengan FormMixin (pada dasarnya semua CBV yang membuat atau mengedit data) dapat menggunakan initialvariabel tingkat kelas (untuk default yang tidak berubah) atau Anda dapat mengganti FormMixin.get_initial()untuk mengembalikan dikt nilai awal yang akan diteruskan ke konstruktor formulir (untuk default dinamis) .)
GDorn

29

Solusi lain: Tetapkan inisial setelah membuat formulir:

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

Ini berfungsi untuk kebutuhan saya, hanya init satu bidang dalam formulir. Terima kasih.
bl4ckb1rd


11

Saya punya solusi lain ini (saya mempostingnya kalau-kalau ada orang lain karena saya menggunakan metode berikut dari model):

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',

            })
        }

Inisial ditetapkan pada __init__fungsi sebagaiself.fields['is_active'].initial = False


0

Saya harap ini dapat membantu Anda:

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

0

Seperti yang dijelaskan dalam dokumen Django , initialtidak default.

  • Nilai awal suatu bidang dimaksudkan untuk ditampilkan dalam HTML. Tetapi jika pengguna menghapus nilai ini, dan akhirnya mengirim kembali nilai kosong untuk bidang ini, initialnilainya hilang. Jadi, Anda tidak mendapatkan apa yang diharapkan oleh perilaku default .

  • The standar perilaku: nilai bahwa proses validasi akan mengambil jika dataargumen tidak mengandung nilai untuk lapangan.

Untuk mengimplementasikannya, cara mudah adalah menggabungkan initialdan 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']
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.