Django varsayılan form değerlerini ayarlama


241

Aşağıdaki gibi bir Modelim var:

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

Ayrıca yukarıdaki model için aşağıdaki gibi bir model formu var:

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

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

Tank gizli alanı için varsayılan değerin nasıl ayarlanacağını bilmek istiyorum. İşte şimdiye kadar formu göstermek / kaydetmek için benim işlevi:

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

Yanıtlar:


402

Burada açıklanan ilk harfleri kullanabilirsiniz

Form yapıcısını çağırırken değeri dolduran iki seçeneğiniz vardır:

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

veya form tanımındaki değeri ayarlayın:

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

Ve bu değişken initialasıl forma nasıl aktarılır? Gerçek form modelinde, parametre / argüman olarak yazmak zorunda mıyız?
mgPePe

2
@bharal Bu sihir. ;-) (Daha doğrusu, Django form oluşturucuları özel "ilk" değişkeni anlar ve ekstra bir şey yapmanıza gerek kalmadan içeriği üzerinden yineleme yapar). Şahsen, form tanımında varsayılan değerleri belirtmeyi tercih ediyorum ve sadece initial = ... mekanizmasını yalnızca istenen varsayılan dinamik bir değerse (örneğin, kullanıcı tarafından girilen veya oturum açma, coğrafi konum vb.
Richard J Foster

66
initial varsayılan değildir. Form bağlanmışsa ilk değer geçerli değildir :(.
clime

4
Bu ilk param çözümünün yardımcı olacağı başka bir kullanıcı tabanından bahsetmek için yorum yapmak: Kayıt formunda e-posta / kimlik veya başka herhangi bir kimlik bilgisini önceden doldurmak istiyorsanız birisine bir kayıt bağlantısı gönderirken, bu durumda bunu yazamazsınız. modelin kendisi dinamik olarak onun yerine yapıcıya @ umnik700 tarafından belirtildiği gibi ilk parametre ile çağırmanız gerekir. Harika çalışıyor!
Keshav Agrawal

1
@Phlip: View.get_formBaşlangıç ​​verilerini ayarlamak için geçersiz kılmayın . FormMixin (temel olarak veri oluşturan veya düzenleyen tüm CBV'ler) olan herhangi bir CBV, sınıf düzeyinde bir initialdeğişken kullanabilir (değişmeyen varsayılanlar için) veya FormMixin.get_initial()formun yapıcısına iletilecek başlangıç ​​değerlerinin bir diksiyonunu (dinamik varsayılanlar için) döndürmek için geçersiz kılabilirsiniz .)
GDorn

29

Diğer çözüm: Formu oluşturduktan sonra ilkini ayarlayın:

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

Bu iş benim ihtiyacım için, sadece formdaki bir alanı başlatır. teşekkür ederim.
bl4ckb1rd


11

Bu başka bir çözüm vardı (benim gibi bir başkası modelden aşağıdaki yöntemi kullanıyorsa) gönderiyorum:

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

            })
        }

İlk __init__fonksiyondaself.fields['is_active'].initial = False


0

Umuyorum ki bu sana yardım edebilir:

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

0

Açıklandığı gibi Django dokümanlar , initialdeğil default.

  • Başlangıç alanı değeri bir HTML olarak görüntülenebilir amaçlanmıştır. Ancak kullanıcı bu değeri silip sonunda bu alan için boş bir değer gönderirse, initialdeğer kaybolur. Böylece varsayılan bir davranışla beklenenleri elde edemezsiniz .

  • Varsayılan davranış: if değeri o doğrulama işlemi alacak dataargüman alan için herhangi bir değer içermiyor.

Bunu uygulamak için basit bir yol birleştirmek initialve 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']
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.