2014-03-30 130 views
16

我創建了一個模型學生,它從Django用戶擴展,是另一個模型的外鍵,而它有一個稱爲year的整數字段。我想要做的是保存一個表單,其中有2個字段。一個是當然編號和另一個是整數字段。當我點擊提交時,出現錯誤無法指定「u'2'」:「Student.course」必須是「課程」實例。Django,保存ModelForm

models.py

class Student(models.Model): 
    user = models.OneToOneField(User) 
    course = models.ForeignKey(Course) 
    year = models.IntegerField(validators=[MinValueValidator(1), 
              MaxValueValidator(7)]) 

view.py

def step3(request): 
    user = request.user 
    if request.method == 'POST': 
     form = SelectCourseYear(request.POST) 
     if form.is_valid(): 
      form.save() 
      return render_to_response("registration/complete.html", RequestContext(request)) 
    else: 
     form = SelectCourseYear() 
    return render(request, 'registration/step3.html',) 

forms.py

class SelectCourseYear(forms.ModelForm): 
    course = forms.CharField() 
    year = forms.IntegerField(required=True) 

    class Meta: 
     model = Student 
     fields = ['user', 'course', 'year'] 
+1

你能嘗試,而不是'form.save()'寫3行代碼:'obj = form.save(commit = False)','obj.course_id = request.POST ['course']'然後'obj.save()'? – alecxe

+0

嘗試過但仍然出現此錯誤**無法分配「u'1'」:「Student.course」必須是「課程」實例** – manosim

+0

您在哪裏指定用戶的課程?因爲我沒有得到你分配課程屬性的代碼。 –

回答

29

你不需要重新定義字段中ModelForm如果你已經在fields提到他們一個實例屬性。所以,你的形式應該是這樣的 -

class SelectCourseYear(forms.ModelForm): 
    class Meta: 
     model = Student 
     fields = ['course', 'year'] # removing user. we'll handle that in view 

我們可以輕鬆處理視圖的形式 -

def step3(request): 
    user = request.user 
    if request.method == 'POST': 
     form = SelectCourseYear(request.POST) 
     if form.is_valid(): 
      student = form.save(commit=False) 
      # commit=False tells Django that "Don't send this to database yet. 
      # I have more things I want to do with it." 

      student.user = request.user # Set the user object here 
      student.save() # Now you can send it to DB 

      return render_to_response("registration/complete.html", RequestContext(request)) 
    else: 
     form = SelectCourseYear() 
    return render(request, 'registration/step3.html',) 
+0

是的!這是正確的!謝謝!! – manosim

+0

這對我不起作用。在爲尚未擁有該模型實例的用戶提交此表單時,出現'NOT NULL約束失敗:appname_modelname.user_id'錯誤。 – Pieter

3

course必須是一個場模型的實例,而不僅僅是主實例的關鍵。您仍然可以接受表單中的ID作爲文本輸入,但您需要檢索實際課程實例並分配值。

您需要驗證課程ID是否有效,因此將該代碼放入乾淨的方法並不是一個壞主意。還請注意course字段在這裏排除?否則,表單會期望它存在。您也不需要重新定義year字段,因爲ModelForm將從Student模型繼承該字段。

# forms.py 

class SelectCourseYear(forms.ModelForm): 
    class Meta: 
     model = Student 
     exclude = ['user', 'course'] 

    course_id = forms.IntegerField() 

    def __init__(self, *args, **kwargs): 
     self.user = kwargs.pop('user') 
     super(SelectCourseYear, self).__init__(*args, **kwargs) 

    def clean_course_id(self): 
     course_id = self.cleaned_data.get('course_id') 
     try: 
      self.course = Course.objects.get(pk=course_id) 
     except Course.DoesNotExist: 
      raise forms.ValidationError('Sorry, that course id is not valid.') 

     return course_id 

    def save(self, commit=True): 
     instance = super(SelectCourseYear, self).save(commit=False) 
     instance.course = self.course 
     instance.user = self.user 
     if commit: 
      instance.save() 
     return instance 


# views.py 

def step3(request): 
    if request.method == 'POST': 
     form = SelectCourseYear(request.POST or None, user=request.user) 
     if form.is_valid(): 
      form.save() 
      return render_to_response("registration/complete.html", 
       RequestContext(request)) 
    return render(request, 'registration/step3.html',) 

現在,當你在模型上調用.save(),課程場將被分配的Course

+0

不幸的是,我收到一個錯誤,說** int()參數必須是字符串或數字,而不是'課程'**。 – manosim

+0

對不起,這是我的錯。我將字段名稱從「course」更改爲「course_id」以防止類型衝突,並忘記更新干淨的方法名稱。 – Brandon

+0

噢!現在它不會返回錯誤,但仍不會更新數據庫。所以在管理面板中,兩個字段(課程和年份)都是空的。 – manosim

相關問題