2014-03-30 11 views
16

ich ein Modell Studenten erstellt habe, die von den Django Benutzern erweitert und ist ein Fremdschlüssel zu einem anderen Modell, während es ein ganzes Feld Jahr genannt hat. Was ich versuche, ist ein Formular zu speichern, das 2 Felder hat. Die eine ist die Kurs-ID und die andere ist das Integer-Feld Jahr. Wenn ich auf submit klicke, erhalte ich einen Fehler Kann "u'2 'nicht zuweisen": "Student.course" muss eine "Kurs" -Instanz sein.Django, speichert 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

Könnten Sie versuchen, statt 'form.save()' schreiben 3 Zeilen Code : 'obj = form.save (commit = False)', 'obj.course_id = request.POST ['Kurs']' und dann 'obj.save()'? – alecxe

+0

Versucht es, aber immer noch diesen Fehler ** Kann nicht zuweisen "u'1 '": "Student.course" muss eine "Kurs" -Instanz sein. ** – manosim

+0

Wo weisen Sie den Kurs des Benutzers zu? da ich den Code nicht erhalte, wo Sie das Kursattribut zuweisen. –

Antwort

29

Sie brauchen nicht zugeordnet werden, neu zu definieren Felder in der ModelForm, wenn Sie sie bereits in der fields erwähnt habe Attribut. So Ihre Form sollte wie folgt aussehen -

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

Und wir können die Form mit Leichtigkeit in der Ansicht Griff -

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

Ja! Das ist richtig! Vielen Dank!! – manosim

+0

Dies funktioniert nicht für mich. Ich erhalte den Fehler 'NOT NULL constraint failed: appname_modelname.user_id', wenn ich dieses Formular für einen Benutzer absende, der noch keine Instanz des Modells hat. – Pieter

3

course hat eine Instanz eines Kursmodell sein, nicht nur die primären Schlüssel der Instanz. Sie können weiterhin eine ID im Formular als Texteingabe akzeptieren, aber Sie müssen die tatsächliche Kursinstanz abrufen und den Wert zuweisen.

Sie müssen überprüfen, ob die Kurs-ID gültig ist. Es ist also keine schlechte Idee, diesen Code in die clean-Methode zu schreiben. Beachten Sie auch, wie das Feld course hier ausgeschlossen ist? Andernfalls erwartet das Formular, dass es vorhanden ist. Sie müssen das Jahr-Feld auch nicht neu definieren, da das ModelForm dieses Feld vom Student-Modell erbt.

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

Wenn Sie jetzt .save() auf dem Modell aufrufen, wird der Kurs Feld eine Instanz von Course

+0

Leider bekomme ich eine Fehlermeldung, dass ** int() Argument eine Zeichenfolge oder eine Zahl sein muss, nicht 'Kurs' **. – manosim

+0

Entschuldigung, das ist meine Schuld. Ich habe den Feldnamen von "Kurs" in "Kurs-ID" geändert, um eine Typ-Kollision zu verhindern, und habe vergessen, den Namen der Clean-Methode zu aktualisieren. – Brandon

+0

Oh ok! Jetzt gibt es keinen Fehler zurück, aber die Datenbank wird nicht aktualisiert. Im Admin-Panel sind also beide Felder (Kurs und Jahr) leer. – manosim