2015-08-27 107 views
3

我有一個表格:Django的:驗證在的ModelForm unique_together限制與排斥領域

class CourseStudentForm(forms.ModelForm): 

    class Meta: 
     model = CourseStudent 
     exclude = ['user'] 

對於一些複雜的要求的模型:

class CourseStudent(models.Model): 

    user = models.ForeignKey(settings.AUTH_USER_MODEL) 
    semester = models.ForeignKey(Semester) 
    block = models.ForeignKey(Block) 
    course = models.ForeignKey(Course) 
    grade = models.PositiveIntegerField() 

    class Meta: 
     unique_together = (
      ('semester', 'block', 'user'), 
      ('user','course','grade'), 
     ) 

我希望新的對象來使用當前已登錄的用戶CourseStudent.user:

class CourseStudentCreate(CreateView): 
    model = CourseStudent 
    form_class = CourseStudentForm 
    success_url = reverse_lazy('quests:quests') 


    def form_valid(self, form): 
     form.instance.user = self.request.user 
     return super(CourseStudentCreate, self).form_valid(form) 

但是,這是有效的,因爲用戶是而不是表單的一部分,它忽略了Django否則會對unique_together限制做出的驗證。

如何獲得我的表單和視圖以使用Django對這些約束進行驗證而不必自己寫?

我雖然將用戶傳遞給表單中的隱藏字段(而不是排除它),但這似乎是不安全的(即用戶值可能會更改)?

回答

3

設置form.instance.userform_valid爲時已晚,因爲表單已經過驗證。由於這是您的form_valid方法唯一的自定義事項,因此您應該將其刪除。

您可以覆蓋get_form_kwargs,並在CourseStudent實例傳遞已設置的用戶:

class CourseStudentCreate(CreateView): 
    model = CourseStudent 
    form_class = CourseStudentForm 
    success_url = reverse_lazy('quests:quests') 

    def get_form_kwargs(self): 
     kwargs = super(CreateView, self).get_form_kwargs() 
     kwargs['instance'] = CourseStudent(user=self.request.user) 
     return kwargs 

這是不夠的,使其工作,因爲表單驗證跳過唯一一起引用約束user字段。解決方法是覆蓋模型表單的full_clean()方法,並在模型上明確調用validate_unique()。覆蓋clean方法(正如您通常所做的那樣)不起作用,因爲該實例尚未使用表單中的值填充該點。

class CourseStudentForm(forms.ModelForm): 

    class Meta: 
     model = CourseStudent 
     exclude = ['user'] 

    def full_clean(self): 
     super(CourseStudentForm, self).full_clean() 
     try: 
      self.instance.validate_unique() 
     except forms.ValidationError as e: 
      self._update_errors(e) 
+0

使用此代碼,我收到此錯誤:在/課程 類型錯誤/創建/ 'ModelFormMetaclass對象參數**後必須是一個映射,不NoneType' – 43Tesseracts

+0

我已經錯過了在'return語句get_form_kwargs',請你再試一次。如果您仍然遇到錯誤,請使用完整回溯更新您的問題 - 通常只有一行不足以查看發生了什麼。 – Alasdair

+0

(感謝您的幫助) 形式的作品,但不驗證模型:在/課程 IntegrityError /創建/ '唯一約束失敗:courses_coursestudent.semester_id,courses_coursestudent.block_id,courses_coursestudent.user_id' – 43Tesseracts