首页 > 解决方案 > 如何让 FormSet 在我的视图中验证?

问题描述

我正在用 FormSets 做一些不寻常的事情。我正在尝试使用查询集作为我的表单集的输入。这似乎在这一点上工作得很好。无效的是表单验证。提前感谢您的任何想法。由于我不会打扰人们的原因,我无法通过传统的外键创建这种关系。

我的模型.py

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_pk = models.integerfield(Team,null=True)

我的观点.py

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

def get_context_data(self, **kwargs):
    context = super(CreateTeamView, self).get_context_data(**kwargs)
    dropdown = self.request.GET.get("dropdown", None)
    queryset = Player.objects.filter(company_pk=dropdown)
    player_form = PlayerFormSet(queryset=queryset,dropdown=dropdown)
    context['player_form'] = player_form
    context['dropdown'] = dropdown
    return context

def get_form_kwargs(self):
    kwargs = super(CreateTeamView,self).get_form_kwargs()
    kwargs['user'] = self.request.user
    kwargs['dropdown'] = self.request.GET.get("dropdown")
    return kwargs

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

    dropdown=self.request.GET.get("dropdown")

    self.object = self.get_object()
    context = self.get_context_data(object=self.object)

    self.object = None
    context = self.get_context_data(object=self.object)
    form_class = self.get_form_class()
    form = self.get_form(form_class)
    form_kwargs = self.get_form_kwargs()
    player_form = PlayerFormSet(dropdown=dropdown)
    return self.render_to_response(
        self.get_context_data(form=form,
                              player_form=player_form,
                              context=context,
                              ))

def form_valid(self, form, player_form):
    self.object = form.save()
    player_form.instance = self.object
    player_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)
    dropdown=self.request.GET.get("dropdown")
    player_form = PlayerFormSet(dropdown,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

        fields=['team_name',]

PlayerFormSet = inlineformset_factory(Team, Player, extra=0, fields=['player_name',])

class PlayerFormSet(PlayerFormSet,BaseInlineFormSet):
    def __init__(self, dropdown, *args, **kwargs,): 
        super(PlayerFormSet, self).__init__(*args, **kwargs)
        self.queryset = Player.objects.filter(teamp_pk=dropdown)

我的模板...

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

{% csrf_token %}

    {{ player_form.management_form }}

    {{ player_form.non_form_errors }}

    {% for hidden in player_form.management_form %}
        {{ hidden }}
    {% endfor %}

    {% for form in player_form.forms %}

      {{ 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>

        {% if player_form.non_form_errors %}

          <h3 class="spacer12">
            {{ player_form.non_form_errors }}
          </h3>

        {% endif %}

        {% if form.player_name.errors %}

          <h3 class="spacer12">
            {{ form.player_name.errors }}
          </h3>

        {% endif %}

    {% endfor %}

</form>

好消息是这一切都在起作用,因为它现在正在将我所追求的表单集数据传递给表单。我现在坚持的是表单集处理。因为表单数据是全新的......我意识到我需要通过代码的 form_valid 部分进行某种循环,但我无法完全理解......

我试过了...

data = self.get_context_data()
formset = data['player_form']
if formset.is_valid():
    self.object = form.save()
    formset.instance = self.object
    formset.save()

但我确实收到零错误消息。如果我不更改任何内容,表单将提交。但这违背了目的。我需要能够更改表单中的数据,然后提交。

更新......我已经更进一步......在我的帖子功能中使用下面的代码......在我的基于类的视图中......

def post(self, request, *args, **kwargs):
    self.object = None
    form_class = self.get_form_class()
    form = self.get_form(form_class)
    dropdown=self.request.GET.get("dropdown")
    team_form = TeamFormSet(dropdown,self.request.POST)
    if (form.is_valid() and team_form.is_valid()):
        players = team_form.save(commit=False)
        for player in players:
            player = form.save(commit=False)
            player.save()
        return self.form_valid(form, team_form)

这种作品。有时。如果我通过视图更新表单并删除一个条目......保存将不起作用,说 save() 禁止以防止由于未保存的相关对象而导致数据丢失。我今天大部分时间都在查看原子保存和不同程度的表单集保存,但没有任何效果。提前感谢您对我可能做错的任何想法。

更新...

        team_form = TeamForm(request.POST)
        player_form = PlayerForm(self.request.POST)
        if player_form.is_valid():
            for form in team_form:
                print("works")
            player_form.save()
            return HttpResponseRedirect(reverse('Team:main_menu'))
        else:
            for form in team_form:
                if form.is_valid():
                    form.save(commit=False)
                    print("nope")
                else:
                    print(form.errors)
                # return HttpResponseRedirect(reverse('Team:team_menu'))
                return self.form_invalid(form, playerform)

我现在可以遍历我的表单集,并确定错误在哪里,但是当我这样做时,它会返回对象没有属性“对象”。

这是追溯数据...

异常类型:TypeError at /Company/update_saved_new_company/ 异常值:form_invalid() 采用 2 个位置参数,但给出了 3 个

对象的回溯数据没有属性“对象”

Traceback (most recent call last):
  File "C:\Users\steve\Envs\Final5Production\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\steve\Envs\Final5Production\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\steve\Envs\Final5Production\lib\site-packages\django\views\generic\base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Project\Project\mixins.py", line 46, in dispatch
    return super().dispatch(request, *args, **kwargs)
  File "C:\Users\steve\Envs\Final5Production\lib\site-packages\django\contrib\auth\mixins.py", line 52, in dispatch
    return super().dispatch(request, *args, **kwargs)
  File "C:\Users\steve\Envs\Final5Production\lib\site-packages\django\views\generic\base.py", line 98, in dispatch
    return handler(request, *args, **kwargs)
  File "C:\Company\views.py", line 9283, in post
    return super(UpdateSavedNewCompanyView, self).form_invalid(company_contact_form)
  File "C:\Users\steve\Envs\Final5Production\lib\site-packages\django\views\generic\edit.py", line 61, in form_invalid
    return self.render_to_response(self.get_context_data(form=form))
  File "C:\Company\views.py", line 9036, in get_context_data
    context = super(UpdateSavedNewCompanyView, self).get_context_data(**kwargs)
  File "C:\Users\steve\Envs\Final5Production\lib\site-packages\django\views\generic\edit.py", line 67, in get_context_data
    return super().get_context_data(**kwargs)
  File "C:\Users\steve\Envs\Final5Production\lib\site-packages\django\views\generic\detail.py", line 94, in get_context_data
    if self.object:

Exception Type: AttributeError at /Company/update_saved_new_company/
Exception Value: 'UpdateSavedNewCompanyView' object has no attribute 'object'

标签: djangodjango-modelsdjango-viewsdjango-formsdjango-templates

解决方案


推荐阅读