【问题标题】:How do I properly implement Django formsets with a CreateView ( Class Based View )?如何使用 CreateView (基于类的视图)正确实现 Django 表单集?
【发布时间】:2021-06-26 19:04:58
【问题描述】:

提前感谢您的任何建议。几天来,我一直在研究如何使用 CreateView 正确实现表单集,但我被困住了。这是我的代码。

我的模特:

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 来进行验证,如下所示....

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 还是可能是我的 HTML 模板有关?这就是我卡住的地方。

我尝试做类似...

  $(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 号以外的玩家。不知道我做错了什么。

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

【问题讨论】:

    标签: django django-models django-views django-forms django-templates


    【解决方案1】:

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

    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)
    

    我的观点.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)
    

    我的表单.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)

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-26
      • 2017-11-07
      • 2014-01-22
      • 1970-01-01
      • 1970-01-01
      • 2015-12-04
      • 1970-01-01
      • 2018-11-30
      相关资源
      最近更新 更多