Skip to content

Instantly share code, notes, and snippets.

@neara
Last active Apr 13, 2022
Embed
What would you like to do?
Django Class Based Views and Inline Formset Example
from django.forms import ModelForm
from django.forms.models import inlineformset_factory
from models import Sponsor, Sponsorship
class SponsorForm(ModelForm):
class Meta:
model = Sponsor
class SponsorshipForm(ModelForm):
class Meta:
model = Sponsorship
SponsorShipsFormSet = inlineformset_factory(Sponsor, Sponsorship,
form=SponsorshipForm, extra=2)
from django.db import transaction
from django.views.generic import CreateView
from forms import SponsorForm, SponsorShipsFormSet
class CreateSponsor(CreateView):
form_class = SponsorForm
template_name = 'sponsor_form.html'
def get_context_data(self, **kwargs):
data = super(CreateSponsor, self).get_context_data(**kwargs)
if self.request.POST:
data['sponsorships'] = SponsorShipsFormSet(self.request.POST)
else:
data['sponsorships'] = SponsorShipsFormSet()
return data
def form_valid(self, form):
context = self.get_context_data()
sponsorships = context['sponsorships']
with transaction.commit_on_success():
form.instance.created_by = self.request.user
form.instance.updated_by = self.request.user
self.object = form.save()
if sponsorships.is_valid():
sponsorships.instance = self.object
sponsorships.save()
return super(CreateSponsor, self).form_valid(form)
def get_success_url(self):
return reverse('sponsors')
@halfnibble
Copy link

halfnibble commented Apr 10, 2015

You have save my life. Why isn't this a more obvious process?

BTW, is there any reason you use get_context_data() to instantiate the formset, instead of just doing it directly in form_valid()?

@dmitrysus
Copy link

dmitrysus commented Jun 5, 2015

SponsorMixin? What is that mean?

@rmosolgo
Copy link

rmosolgo commented Aug 22, 2015

Thanks! I had to change this to pass instance=self.object when initializing the formset.

@EmadMokhtar
Copy link

EmadMokhtar commented Dec 7, 2015

@rmosologo Is the relationship between Sponsor and Sponsorship are one-to-many or one-to-one? and What is SponsorMixin?

@hurta2yaisel
Copy link

hurta2yaisel commented Mar 19, 2017

What the hell is SponsorMixin?

@MiniGunnR
Copy link

MiniGunnR commented Apr 28, 2017

Can I use it for updating multiple entries at the same time? If so, can anyone refer me to a good tutorial?

@koslib
Copy link

koslib commented Jun 4, 2017

Any luck finding how we use this with UpdateView instead of just CreateView, so that we update also stuff?

@tonysyu
Copy link

tonysyu commented Jun 6, 2017

@koslibpro: You can find an example with UpdateView here: https://github.com/timhughes/django-cbv-inline-formset

@miguelcb84
Copy link

miguelcb84 commented Jun 16, 2017

In that case I guess you need to tell the formset to use the instance:

data['sponsorships'] = SponsorShipsFormSet(self.request.POST, instance=self.object)
...
data['sponsorships'] = SponsorShipsFormSet(instance=self.object)

@leonardocintra
Copy link

leonardocintra commented Jun 30, 2017

My site is in error in UpdateView

form show duplicate
image

forms.py

class ExameUrinaRotinaForm(forms.ModelForm):
     
     class Meta:
         model = ExameUrinaRotina
         exclude = ()

ExameUrinaRotinaFormSet = inlineformset_factory(Laudo, ExameUrinaRotina, form=ExameUrinaRotinaForm, extra=1)

views.py

def get_context_data(self, **kwargs):
        context = super(UrinaRotinaUpdate, self).get_context_data(**kwargs)
        if self.request.POST:
            context['form_urina_rotina'] = ExameUrinaRotinaFormSet(self.request.POST, instance=self.object)
            context['form_urina_rotina'].full_clean()
        else:
            context['form_urina_rotina'] = ExameUrinaRotinaFormSet(instance=self.object)
        return context

urina_rotina_update.html

{{ form_urina_rotina.management_form }}

{% for form in form_urina_rotina %}
    <div class="form-group">
        <label class="col-sm-2 control-label">{{ form.volume.label }}</label>
        {{ form.volume }}
    </div>
{% endfor %}

@OmarNour
Copy link

OmarNour commented Sep 6, 2017

can you show us sponsor_form.html ?

@vmonteco
Copy link

vmonteco commented Oct 3, 2017

Interesting and helpful, but is SponsorMixin specific to the case you used for the example or is it specific to the usage of inline_formsets with CreateView?

@surfer190
Copy link

surfer190 commented Oct 23, 2017

This thing is old now module 'django.db.transaction' has no attribute 'commit_on_success'

@nix1947
Copy link

nix1947 commented Jun 8, 2018

SponsorForm get saved even though SponsorShipsFormSet are invalid

@zypro
Copy link

zypro commented Jul 6, 2018

Maybe this update helps:

    def form_valid(self, form):
        context = self.get_context_data()
        sponsorships = context['sponsorships']
        with transaction.atomic():
            form.instance.created_by = self.request.user
            form.instance.updated_by = self.request.user
            self.object = form.save()
            if sponsorships.is_valid():
                sponsorships.instance = self.object
                sponsorships.save()
        return super(CreateSponsor, self).form_valid(form)

@addohm
Copy link

addohm commented Aug 19, 2019

What the hell is SponsorMixin?

He's not actually using that in his code but it's basically an input parameter.

@yarickprih
Copy link

yarickprih commented Mar 3, 2020

Do you guys know how to implement update_or_create method for inline model to exclude possibility of adding 2 or more similar instances?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment