J'ai créé un modèle Student qui s'étend de Django User et est une clé étrangère vers un autre modèle alors qu'il a un champ entier appelé year. Ce que j'essaie de faire, c'est d'enregistrer un formulaire qui comporte 2 champs. L'un est le id du cours et l'autre est le champ entier année. Lorsque je clique sur Soumettre, je reçois une erreur Impossible d'attribuer "u'2 '": "Student.course" doit être une instance de "Course".
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']
Vous n'avez pas besoin de redéfinir les champs de ModelForm
si vous les avez déjà mentionnés dans l'attribut fields
. Votre formulaire devrait donc ressembler à ceci -
class SelectCourseYear(forms.ModelForm):
class Meta:
model = Student
fields = ['course', 'year'] # removing user. we'll handle that in view
Et nous pouvons gérer le formulaire avec facilité dans la vue -
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',)
course
doit être une instance d'un modèle de cours, pas seulement la clé primaire de l'instance. Vous pouvez toujours accepter un identifiant dans le formulaire comme entrée de texte, mais vous devrez récupérer l'instance de cours réelle et attribuer la valeur.
Vous devrez vérifier que l'ID du cours est valide, donc mettre ce code dans la méthode propre n'est pas une mauvaise idée. Remarquez également comment le champ course
est exclu ici? Sinon, le formulaire s'attendra à ce qu'il soit présent. Vous n'avez pas non plus besoin de redéfinir le champ année, car ModelForm héritera de ce champ du modèle 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',)
Maintenant, lorsque vous appelez .save()
sur le modèle, le champ de cours se verra attribuer une instance de Course