如何使用CreateView(基于类的视图)正确实现Django表单集? [英] How do I properly implement Django formsets with a CreateView ( Class Based View )?

查看:52
本文介绍了如何使用CreateView(基于类的视图)正确实现Django表单集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此先感谢您的任何建议.几天来,我一直在研究如何使用CreateView正确实现表单集,但我一直处于困境.这是我的代码.

And thanks in advance for any suggestions. I have been playing around with how to properly implement formsets with a CreateView for a couple of days and I'm stuck. Here is my code.

我的模特:

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)

我的观点:

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

    def get_context_data(self, **kwargs):
        context = super(CreateTeamView, self).get_context_data(**kwargs)
        if self.request.POST:
            context['new_player'] = NewPlayerFormSet(self.request.POST)
        else:
            context['nwe_player'] = NewPlayerFormSet()
        return context

    def get_form_kwargs(self, *args, **kwargs):
        kwargs = super(CreateTeamView, self).get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

    def form_valid(self, form):

        context = self.get_context_data()
        new_player_form = context['new_player']

        if new_player_form.is_valid():
            self.object = form.save()
            new_player_form.instance = self.object
            new_player_form.save()
            instance = form.save()
        else:
            return self.render_to_response(self.get_context_data(form=form))

我的表格:

class CreateTeamForm(forms.ModelForm):

    class Meta:
        model = Team
        exclude = []

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

我的HTML:

 <div="players>

  <div="add_players">

{{ new_player.management_form }}

{% for form in new_player %}

{{ form.id }}

{{ form.player_name }}

   </div>
 </div>

我的表单正在保存一个玩家,但是当我尝试更新代码以使用初始CreateView保存多个玩家时,它只能识别第一个联系人.我已覆盖BaseInlineFormset进行验证,如下所示.

My form is saving one player, but when I try to update the code to save more than one player with the initial CreateView, it only recognizes the first contact. I have overridden the BaseInlineFormset to do validation as shown below....

class NewPlayerFormSet(NewPlayerFormSet,BaseInlineFormSet):

        player_name = forms.CharField(required=True,widget=forms.TextInput)

        def add_fields(self, form, index):
            super(NewPlayerFormSet,self).add_fields(form,index)
            form.fields['player_name'].required = False

        def clean(self):

            super(NewPlayerFormSet, self).clean()

            for form in self.forms:
                if form.cleaned_data.get('player_name'):
                    pass
                else:
                    form.add_error('player_name','Player Name is required.')
                    pass

我正在尝试获取代码以保存第二个联系人.我已经尝试过各种JQuery尝试....但是不清楚我的问题是JQuery还是mayby我的HTML模板?那就是我被困住的地方.

I'm trying to get the code to save a second contact. I have used tried various JQuery attempts....but am unclear if my problem is with JQuery or mayby my HTML templates? That's where I'm stuck.

我试图做类似...

  $(document).ready(function() {

       // Watch for the 'add player' click
       $('#add_player').click(function(e) {
           e.preventDefault();
           
           $('div.add_player:last').clone().each(function(i) {
               $(this).find('input,select').each(function(i) {

                   // Remove any existing values
                   $(this).val('');

           }).appendTo('div#players');

       });
   });  

尽管这可以复制表格,但不会保存1号以外的玩家.不确定我做错了什么.

And while this works to duplicate the form, the players beyond number 1 are not being saved. Not sure what I'm doing incorrectly.

它似乎为此提供了一个JQuery插件,但是出于多种原因,我试图避免使用它.再次感谢您为我指明正确方向的帮助.

It would appear there is a JQuery plugin for this, but I'm trying to avoid using it for a number of reasons. Thanks again for any help to point me in the right direction.

推荐答案

这并不容易.我花了大约一周的时间试图将它们拼凑在一起.这是我最后用来使它工作的所有部分.我最终在解决方案中使用了来自GitHub的jquery.formset.js.希望我能救一个星期.

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)

我的Views.py

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)

我的Forms.py

My Forms.py

class CreateTeamForm(forms.ModelForm):

class Meta:
    model = Team
    exclude = [ ]

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

我的HTML模板:(使用jquery/jquery.formset.js)

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 %}

这篇关于如何使用CreateView(基于类的视图)正确实现Django表单集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆