2012-02-12 79 views
0

我需要爲事件創建註冊表單。每個註冊的人都可以帶來客人。我想在一個頁面中註冊所有內容。爲此,我使用1 RegistrationForm和X GuestForm s的視圖。在我的模型中,我有一個RegistrationGuest類,我用它來創建ModelForm這兩個表單。Django提交可選表單

問題是GuestForm不需要填充(您不必攜帶客人)。

def register_form(request): 
    error = False 
    if request.method == 'POST': 
    register = RegistrationForm(request.POST, instance=Registration()) 
    guests = [GuestForm(request.POST, prefix=str(x), instance=Guest()) for x in range(MAXGUESTS)] 
    if register.is_valid(): 
     print("register is valid") 

     for guest in guests: 
      if guest.is_valid(): 
       print("guest is valid") 
      else: 
       print("guest is not valid") # always when empty form 
       error = True 
    else: 
     print("register is not valid") 
     error = True 

    if not error: 
     ... # save the form in the database 

    register = RegistrationForm(instance=Registration()) 
    guests = [GuestForm(prefix=str(x), instance=Guest()) for x in range(MAXGUESTS)] 
    return render_to_response('register.html',{ 
     'form': register, 
     'max_guests': MAXGUESTS, 
     'guests': guests, 
     'error': error, 
     }) 

因此,我需要設置一個窗體爲可選項,並且能夠區分整個窗體是否爲空以及何時出現錯誤。任何想法如何?

謝謝


解決方案

def register_form(request): 
    GuestFormSet = modelformset_factory(Guest, exclude=('register',)) 
    error = False 
    if request.method == 'POST': 
    register = RegistrationForm(request.POST, instance=Registration()) 
    guests = GuestFormSet(request.POST) 
    if register.is_valid(): 
     print("register is valid") 

     for guest in guests: 
      if guest.is_valid(): 
       print("guest is valid") # even if some forms are empty 
      else: 
       print("guest is not valid") 
       error = True 
    else: 
     print("register is not valid") 
     error = True 

    if not error: 
     ... 
     # save the form in the database 
     return something 

    else: 
     register = RegistrationForm(instance=Registration()) 
     guests = GuestFormSet(queryset=Guest.objects.none()) 
    return render_to_response('register.html',{ 
     'form': register, 
     'max_guests': MAXGUESTS, 
     'guests': guests, 
     'error': error, 
     }) 

回答

0

我猜你會需要一些方法來確定是否提交來賓形式實際上是填補了當空的形式提交,忽略它。

forms_to_save =[] 

for form in guest_forms: 
    if guest_form.is_valid() 
     forms_to_save.append(form) 
    else: 
     if form.contains_data(): # you'll have to implement this 
      error = True 

if not error: 
    for form in forms_to_save(): 
     form.save() 
+0

我的問題是你提到的一點,我怎麼做contains_data()方法? – 2012-02-12 17:32:36

0

我有一個類似的問題在我正在構建的婚禮RSVP應用程序中。在我的情況下,每個訪客都有一個「參加」複選框,如果沒有選中(即訪客不參加),那麼我不希望向用戶報告任何錯誤。

志雲飯局模型(精簡下來的簡潔):

class Guest(models.Model): 
    email = models.EmailField(max_length=50, unique=True) 
    first_name = models.CharField(max_length=50) 
    last_name = models.CharField(max_length=50) 
    attending = models.BooleanField(default=False) 

我有一個類的ModelForm名爲RsvpForm創建基於來賓模型的形式。它看起來像這樣:

class RsvpForm(ModelForm): 
    class Meta: 
     model = Guest 
     fields = ('attending', 'email', 'first_name', 'last_name') 

    def clean(self): 
     cleaned_data = self.cleaned_data 
     attending = cleaned_data.get('attending') 

     if not attending: 
      #clear the error collection 
      self._errors['email'] = {} 

     return cleaned_data 

解決這個問題的關鍵在於,我在我的RsvpForm類已經重寫了乾淨的()方法。其中,我檢查客人是否參加。如果它們不是,那麼我會清除其他每個字段的錯誤消息。

我本來清除了錯誤的整個形式是這樣的:

if not attending: 
    #clear the error collection 
    self._errors['email'] = '' 
    self._errors['first_name'] = '' 
    self._errors['last_name'] = '' 

但由於某些原因,修改任何這些鍵的值造成的形式驗證失敗,這反過來又防止遊客如果他們表示他們不參加,數據將被保存。大多數人都找不到的小錯誤,但令人討厭。

在沿線的某個時刻,我也試圖通過對self._errors字典調用.clear()來清除錯誤集合:

if not attending: 
    #clear the error collection 
    self._errors.clear() 

但由於某些原因,這些錯誤仍然顯示,儘管我可以確認字典是空的。

最終的結果是,如果選中'參加'複選框,表單驗證錯誤只會顯示給我的用戶,這是理想的,因爲客人可能需要在決定他們將作爲加一。

0

有一個比Alasdair更簡單的解決方案:使用empty_permitted關鍵字參數。

>>> f = MyForm(data={}, empty_permitted=True) 
>>> f.is_valid() 
True