Skip to content

Instantly share code, notes, and snippets.

@neara
Last active February 10, 2023 01:18
Show Gist options
  • Star 55 You must be signed in to star a gist
  • Fork 14 You must be signed in to fork a gist
  • Save neara/6209563 to your computer and use it in GitHub Desktop.
Save neara/6209563 to your computer and use it in GitHub Desktop.
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')
@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

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

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