[Answered ]-How do I properly implement Django formsets with a CreateView ( Class Based View )?

1👍

This was not easy. I spent about a week trying to piece this all together. Here are all of the parts that I used to finally make it work. I ultimately did wind up using jquery.formset.js from GitHub in my solution. Hope I save someone a week.

class Team(models.Model):
    
    team_name = models.CharField(max_length=264,null=False,blank=False)

class Player(models.Model):
    
    player_name = models.CharField(max_length=264,null=False,blank=False)
    team = models.ForeignKey(Team,null=True,on_delete=models.CASCADE)

My Views.py

class CreateTeamView(LoginRequiredMixin,CreateView):
    model = Team
    form_class = TeamForm
    template_name = 'create_team.html'


    def get(self, request, *args, **kwargs):

        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        player_form = CreatePlayerFormSet()
        return self.render_to_response(
            self.get_context_data(form=form,
                                  player_form=player_form,
                                  ))

    def form_valid(self, form, player_form):

        self.object = form.save()
        player_form.instance = self.object
        player_form.save()

        instance = form.save()

    def form_invalid(self, form, player_form):

        return self.render_to_response(
            self.get_context_data(form=form,
                                  player_form=player_form,
                                  ))

    def post(self, request, *args, **kwargs):

        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        player_form = CreatePlayerFormSet(self.request.POST)
        if (form.is_valid() and player_form.is_valid()):
            return self.form_valid(form, player_form)
        else:
            return self.form_invalid(form, player_form)

My Forms.py

class CreateTeamForm(forms.ModelForm):

class Meta:
    model = Team
    exclude = [ ]

CreatePlayerFormSet = inlineformset_factory(Team, Player, extra=1, fields=(['player_name'])

My HTML Template: ( Using jquery/jquery.formset.js )

<script src="{% static 'jquery/jquery.formset.js' %}"></script>
<script type="text/javascript">
    $(function() {
        $(".inline.{{ player_form.prefix }}").formset({
            prefix: "{{ player_form.prefix }}",
        })
    })
</script>

<form method="POST" enctype="multipart/form-data" id="forms">

{% csrf_token %}

{{ player_form.management_form }}

{{ player_form.non_form_errors }}

{% for form in player_form %}

  {{ form.id }}

  <div class="inline {{ player_form.prefix }}">
    <div class="leftwidth22">
      <div class="width52">
        <h2 class="floatright23">Player Name - </h2>
      </div>
    </div>
      <div class="rightwidth53">
        <h2 class="width70">
          {{ form.player_name }}
        </h2>
      </div>

{% endfor %}

Leave a comment