I have a formset in django that uses a model with a one to many relationship. Many attendees can attend a single event.
I am sending the ‘many’ part of the model in a formset. The problem is that the data is returned with no primary key set. I am getting a validation error because the formset primary key data is not set.
Back in my view, I know what the primary key is supposed to be. And i want to set it before validation. Either that or set the value before I send out the form for display. But I don’t know how to set it in the formset data.
In the code below, foreign key is event.
Option 1: Set the foreign key before showing the form:
#models.py - note 2 foreign keys
class Attendee(models.Model):
event = models.ForeignKey(Event)
sponsor = models.ForeignKey(Customer)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
# forms.py
class AttendeeForm(forms.ModelForm):
event = forms.IntegerField(required=True, widget=forms.HiddenInput())
class Meta:
model = Attendee
fields = ( 'last_name', 'first_name', )
exclude = ('event', ) # excluded so user can't set foreign key
# views.py
event = get_object_or_404(Event, id=event_id)
AttendeeFormSet = inlineformset_factory(Event, Attendee, form=AttendeeForm, extra=1)
formset = AttendeeFormSet(instance=event, prefix='attendees')
# Error on form submit:
# Returns and redisplays the form along with message.
# (Hidden field event) The inline foreign key did not match the parent instance primary key.
# I also tried:
#AttendeeFormSet = inlineformset_factory(Event, Customer, Attendee, form=AttendeeForm, extra=1)
# which gave error:
# inlineformset_factory() got multiple values for keyword argument 'form'
Option 2: Set the foreign key on the return POST. Note even though data is present, the form is not valid because foreign key is not set.
formset = AttendeeFormSet(request.POST, request.FILES, prefix='attendees')
i=0
for form in formset.forms:
# How can I set the foreign key (event) field here?
pdb.set_trace()
if formset.is_valid():
attendees = formset.save_all()
(Pdb) p form.fields
{'last_name': <django.forms.fields.CharField object at 0xaa44a2c>,
'first_name': <django.forms.fields.CharField object at 0xaa449ec>,
'event': <django.forms.fields.IntegerField object at 0xaa44fec>}
(Pdb)
What is the best way to fix my foreign key problem in my formset? If Option 2 How do I set this field before I test is_valid?
Since this is a formset representing a foreign key relationship, you should use
inlineformset_factoryto construct the class. That will take care of setting the FKs for you: