【问题标题】:Is it possible to pass a specific value to a django formset?是否可以将特定值传递给 django formset?
【发布时间】:2021-06-30 16:12:47
【问题描述】:

所以我已经使用 Django 表单集大约一个星期了,我准备完全抛弃 Django。开玩笑。有点。 :)。正如我在此处记录的那样,我最终使标准的内联表单集实现工作。 How do I properly implement Django formsets with a CreateView ( Class Based View )?希望对某人有所帮助。现在我试图通过尝试将特定的查询集传递给它来利用此代码,如下所示。

class PlayerFormSet(PlayerFormSet,BaseInlineFormSet):

    def __init__(self, *args, **kwargs):
        super(PlayerFormSet, self).__init__(*args, **kwargs)
        self.queryset = Player.objects.filter(team_pk=20)

如上所示,如果我硬编码一个值,不用担心它可以填充我的表单集。尽管硬编码这个值对实现没有什么价值。我研究了form_kwargs,玩弄了许多实现,如整个SO所示,关于传递一个值,但我尝试的除了上面的代码之外,显然没有为一个团队工作,而且我一生都无法弄清楚如何做类似的事情:

class PlayerFormSet(PlayerFormSet,BaseInlineFormSet):

    def __init__(self, *args, **kwargs):
        super(PlayerFormSet, self).__init__(*args, **kwargs)
        self.queryset = Player.objects.filter(self.object.team_pk)

或者……

class PlayerFormSet(PlayerFormSet,BaseInlineFormSet):

    def __init__(self, *args, **kwargs):
        super(PlayerFormSet, self).__init__(*args, **kwargs)
        self.queryset = Player.objects.filter(self.instance.team_pk)

我知道 pk,它可以清楚地以硬编码的方式传递到这里……而且我认为该值是可访问的。我只是不知道如何将它传递给表单集以获取正确的查询集。这甚至可能吗?这似乎比它应该的更具挑战性。或者当然可以是我。提前感谢您的任何想法。

更新以进行更全面的分析。

我的模型....

class Team(models.Model):

    team_name = models.CharField(null=True) 

class Player(models.Model):

    player_name = models.CharField(null=True) 
    team_pk = models.IntegerField(null=True) 
    team = models.ForeignKey("Team",null=True,on_delete=models.CASCADE)

forms.py

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

class PlayerFormSet(PlayerFormSet,BaseInlineFormSet):

        def __init__(self, *args, **kwargs):
            super(PlayerFormSet, self).__init__(*args, **kwargs)
            self.queryset = Player.objects.filter(team_pk=20)

views.py

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

    def get_context_data(self, **kwargs):
        context = super(UpdateTeamView, self).get_context_data(**kwargs)
        dropdown = self.request.GET.get("dropdown", None)
        queryset = Player.objects.filter(team_pk=dropdown)
        player_form = PlayerFormSet(queryset=queryset)
        context['player_form'] = player_form
        return 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):

        if "cancel" in request.POST:
            return HttpResponseRedirect(reverse('Team:team_main_menu'))
        else:
            self.object = None
            form_class = self.get_form_class()
            form = self.get_form(form_class)
            player_form = PlayerFormSet(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)

我的模板...

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

【问题讨论】:

    标签: django django-rest-framework django-views django-forms django-templates


    【解决方案1】:

    如果这是唯一使用 inlineformset 的视图,那么您可以放弃 BaseInlineFormset 覆盖,只需将查询集提供给视图中的 formset 调用。

    因为这是一个内联表单集,它可以采用父级的实例(而不是对象本身的查询集)。

    def get_context_data(self, **kwargs):
        context = super(UpdateTeamView, self).get_context_data(**kwargs)
        dropdown = self.request.GET.get("dropdown", None)
        instance = Team.objects.get(pk=dropdown)
        player_form = PlayerFormSet(instance=instance)
        context['player_form'] = player_form
        return context
    

    现在 get 部分应该可以工作了。 post 和 form_valid 也需要修复。您无需检查表单,因为所有表单都将通过表单集进行验证。试试:

    def form_valid(self, player_form):
            player_form.save()
            return HttpResponseRedirect('/')
    
    def form_invalid(self, player_form):
        return self.render_to_response(self.get_context_data(player_form=player_form))
    
    def post(self, request, *args, **kwargs):
        if "cancel" in request.POST:
            return HttpResponseRedirect(reverse('Team:team_main_menu'))
        else:
            instance = Team.objects.get(team_pk=dropdown)
            player_form = PlayerFormSet(self.request.POST,instance=instance)
            if player_form.is_valid():
                return self.form_valid(player_form)
            else:
                return self.form_invalid(player_form)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-12
      • 2011-08-21
      • 2016-10-10
      • 1970-01-01
      • 2018-06-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多