Hello all,
I need your advice how to create Form that contains ManyToMany relation and additional fields. I would like to use CBV and ModelForms if possible. This is what I currently have:
models.py
class Person(TimeStampedModel):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
first = models.CharField(_('first'), max_length=64)
last = models.CharField(_('last'), max_length=64)
relation = models.ManyToManyField('self', through='PersonRelation', through_fields=('person','relation'), blank=True)
class PersonRelation(TimeStampedModel):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
person = models.ForeignKey(Person, on_delete=models.PROTECT, related_name='relation_set')
relation = models.ForeignKey(Person, on_delete=models.PROTECT, related_name='+')
type = models.CharField(_('type'), max_length=4, choices=TypeRelation.choices)
views.py
class PersonCreateView(LoginRequiredMixin, CreateView):
model = Person
form_class = PersonModelForm
template_name = 'form.html'
def form_valid(self, form):
person = form.save(commit=False)
person.save()
person.relation.set(form.cleaned_data['relation'],
through_defaults={'type': 'PARENT'})
return super().form_valid(form)
forms.py
class PersonModelForm(forms.ModelForm):
class Meta:
model = Person
fields = ['first',
'last',
'relation']
As you can see my form class PersonModelForm
does not have field type
because it is a part of model PersonRelation
.
I do not know how to create Form that will have all fields from both models Person
and PersonRelation
. I would like to use Model Forms to avoid repeating fields definitions.
Please note that because I currently don’t know how to have the field type
on my form, I put through_defaults={'type': 'PARENT'}
in view PersonCreateView
I would like to have an option to choose the value of field type
on my form instead of that default entry.
I appreciate your advice how to make the Form in a nice and neat way. FormMixin ??? I am not familiar with that, so will be grateful for any help.
I will also appreciate any comment about my current code. Is it something I do wrong?