During form processing, I'd like to be able to set a foreign key field on a model object from its base model when the user selects a value from the dropdown list.
models.py
class Question(models.Model):
question = models.CharField(max_length=200)
class Teacher(models.Model):
name = models.CharField(max_length=200)
l_name = models.CharField(max_length=200)
class Student_Answer(models.Model):
teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
answer = models.SmallIntegerField(choices=RATING_CHOICES)
For example, I have five records in model A, two records in model B and I have two model forms.
forms.py
class AnswerForm(ModelForm):
class Meta:
model = Student_Answer
fields = ('answer',)
widgets = { 'answer': RadioSelect(choices=RATING_CHOICES),}
class TeacherForm(ModelForm):
name = ModelChoiceField(queryset=Teacher.objects.all())
class Meta:
model = Teacher
fields = ('name',)
For the questions, I just assign them directly within the view and then giving the instances to the foreign key after validation. Now, if I do the same for Teacher I mean this teacher = Teacher.objects.get(id=2) and then choice.teacher = teacher it's going to work perfectly. But that is not the case which I want. The teacher will be selected by the user. I am looking for a way like the below view.
views.py
def index(request):
question1 = Question.objects.get(id=6)
question2 = Question.objects.get(id=7)
if request.method == "POST":
teacher_form = TeacherForm(request.POST)
form = AnswerForm(request.POST, prefix='question1')
form1 = AnswerForm(request.POST, prefix='question2')
if (form.is_valid):
choice = form.save(commit=False)
choice.question = question1
choice.teacher = teacher_form
choice.save()
choice = form1.save(commit=False)
choice.teacher = teacher_form
choice.question = question2
choice.save()
return HttpResponseRedirect('/submited/')
else:
teacher_form = TeacherForm()
form = AnswerForm(prefix='question1')
form1 = AnswerForm(prefix='question2')
context = {
'teacher_form': teacher_form,
'form': form,
'form1': form1,
'all_questions': Question.objects.all(),
}
return render(request, 'index.html', context)
The problem with the above example is this error:
ValueError: Cannot assign "<TeacherForm bound=True, valid=Unknown, fields=(name)>": "Student_Answer.teacher" must be a "Teacher" instance.
If I include instance choice.teacher = teacher_form.instance then this error will come up:
Exception Value:
save() prohibited to prevent data loss due to unsaved related object 'teacher'.
And if I save the form in the first line after validation it is going to create a new record for the Teacher class. I do not want to save a new record, I just want to store the selected value in the template and store that value for the Student_Answer class. Is there a way to fix this?
index.html
<form action="{% url 'evaluation:index'%}" method="POST">
{% csrf_token %}
{{ teacher_form }}
{{ all_questions.0 }}
{{ form }}
{{ all_questions.1}}
{{ form1 }}
<input type="submit" value="Vote">
</form>