My code:
# forms.py
class PopupForm(forms.ModelForm):
class Meta:
model = Popup
exclude = ()
class LiveStreamForm(forms.ModelForm):
class Meta:
model = LiveStream
exclude = ("date_created",)
PopupFormSet = inlineformset_factory(LiveStream,Popup,exclude=(),extra=3)
# models.py
class Popup(models.Model):
total_seconds_to_initiate = models.BigIntegerField()
livestream = models.ForeignKey('LiveStream', on_delete=models.CASCADE, blank=True, null=True)
def __str__(self):
return "%s seconds, ls:%s" % (self.total_seconds_to_initiate, self.livestream)
def get_absolute_url(self):
return reverse("livestream_detail", kwargs={
'pk': str(self.livestream.id),})
class LiveStream(models.Model):
youtube_id = models.CharField(max_length=255, blank=True, null=True)
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return "%s (%s)" % (self.youtube_id, self.id)
def get_absolute_url(self):
return reverse("livestream_detail", kwargs={
'pk': str(self.id),})
# views.py
class LiveStreamCreateView(CreateView):
model = LiveStream
form_class = LiveStreamForm
template_name = 'livestream/livestream_create.html'
def get(self, request, *args, **kwargs):
"""
Handles GET requests and instantiates blank versions of the form
and its inline formsets.
"""
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
popup_form_set = PopupFormSet()
return self.render_to_response(
self.get_context_data(form=form,
popup_form_set=popup_form_set,))
def post(self, request, *args, **kwargs):
"""
Handles POST requests, instantiating a form instance and its inline
formsets with the passed POST variables and then checking them for
validity.
"""
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
popup_form_set = PopupFormSet(self.request.POST)
if (form.is_valid() and popup_form_set.is_valid()):
return self.form_valid(form, popup_form_set)
else:
return self.form_invalid(form, popup_form_set)
def form_valid(self, form, popup_form_set):
"""
Called if all forms are valid. Creates a Recipe instance along with
associated Ingredients and Instructions and then redirects to a
success page.
"""
f = form.save(commit=False)
self.object = form.save()
popup_form_set.instance = self.object
popup_form_set.save()
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form, popup_form_set):
"""
Called if a form is invalid. Re-renders the context data with the
data-filled forms and errors.
"""
return self.render_to_response(
self.get_context_data(form=form,
popup_form_set=popup_form_set,))
# livestream_create.html
<form method="POST">
{% csrf_token %}
Enter the Channel ID of the Livestream Here.
{{form}}<br>
{{ popup_form_set.management_form }}
{{ popup_form_set.non_form_errors }}
{% for popup_form in popup_form_set %}
{{popup_form}}<br>
{% endfor %}
<input type="submit" value="Save">
</form>
I want users to be able to create Popup objects on the same page they create Livestream objects. At the moment the form looks like it should work: there's a Livestream Youtube ID field, and 3 Popup total_seconds_to_initiate fields. What should happen is, I enter a youtube ID, then an arbitrary number (=<3) of popups, and I get redirected to the livestream_detail page. Well, I get redirected to the livestream_detail page, but the popups were never created. What is wrong?