I have two models with ManyToMany relationship as this:
class Subject(models.Model):
teachers = models.ManyToManyField(
Teacher
)
subject = models.CharField(
'Materia',
max_length = 50,
unique = True
)
level = models.CharField(
'Nivel',
max_length = 3,
choices = LEVEL_CHOICES
)
class Teacher(Person):
# fields definition
Following the docs I know I can save Subject model without saving Teacher field. That's fine.
Now I want to add a Subject to Teacher, so I need a form with selected teacher, and a choice field with all the subjects.
I found this question that relates to what I want to accomplish, but I think it doesn't address what I'm looking for.
First I populate the subject choice filed, as shown in the ModelForm code below.
forms.py
class SubjectTeacherForm(ModelForm):
subject = forms.ChoiceField(choices=[(m.id, m.subject) for m in Subject.objects.all()])
class Meta:
model = Subject
fields = ['teachers', 'subject']
urls.py
#here I send the teacher id to the view
url(r'^materias/asignar/profesor/(?P<teacher_id>\d+)/$',MateriaTeacherCreateView.as_view(), name='materia-create-teacher'),
views.py
class SubjectTeacherCreateView(SuccessMessageMixin, CreateView):
model = Subject
template_name = 'edu/subject/subject_create.html'
form_class = SubjectTeacherForm
def form_valid(self, form):
# here I want to add the relation
teacher = Teacher.objects.get(pk=self.kwargs['teacher_id'])
# I understad that object here is the ModelForm, not the Model, so this is wrong
self.object.teachers.add(teacher)
return redirect(self.get_success_url())
def get_context_data(self, **kwargs):
context = super(SubjectTeacherCreateView, self).get_context_data(**kwargs)
# here I define the selected teacher to pass to the template
context['teacher'] = Teacher.objects.get(pk=self.kwargs['teacher_id'])
return context
the template
<form method="post" class="form-horizontal">
{% csrf_token %}
{{ form.teacher }}
{{ form.subject }}
As expected, this is not working, the form doesn't save, it throws the error:
AttributeError at /edu/materias/asignar/profesor/11/
'NoneType' object has no attribute 'teachers'
So, obviously I'm doing something wrong.
My question is if I can use class based views to accomplish this, or I should write a method to save the relationship, and what should I change in my code.
I expect I made myself clear enough, thanks.