python - 如何过滤django modelformset manytomany成员的查询集

标签 python django django-forms

我无法使用正确的代码,但我发现了比萨饼/配料问题并且它很接近,所以我正在修改它以提出我的问题。 Django ModelForm for Many-to-Many fields

我们有很棒的披萨和浇头。假设我们经营一家链式店,但并非所有商店都有所有原料。这意味着我们需要一个 Store 类,它有一个位置和一个用于浇头的多对多。然后让我们滚动一个订单,该订单引用一家商店并且在 Pizza 上有 manytomany,因为您经常订购不止一个。

模型.py

from django import models

class Topping(models.Model):
    name = models.TextField()

class Pizza(models.Model):
    size = models.TextField()
    toppings = models.ManyToManyField(Topping)

class Restaraunt(models.Model):
    name = models.TextField()
    toppings = models.ManyToManyField(Topping)


class Order(models.Model):
    customer = models.ForeignKey('User')
    location = models.ForeignKey(Restaraunt)
    pizzas = models.ManyToManyField(Pizza)

表单.py

from django import forms
from django.forms import ModelForm
from models import *

class PizzaForm(ModelForm):

    class Meta:
        model = Pizza

    toppings = forms.ModelMultipleChoiceField(
        widget=forms.CheckboxSelectMultiple(),
        queryset=Topping.objects.all()
    )

View .py

from django.shortcuts import render, redirect, get_object_or_404
from django.forms.models import modelformset_factory
from django.forms import CheckboxSelectMultiple

from models import *
from forms import *


def order_pizzas(request, order_id):
    order_id = int(order_id)
    order = get_object_or_404(Order, id=order_id)

    restaraunt = order.restaraunt

    PizzaFormSet = modelformset_factory(Pizza, form=PizzaForm, extra=1)

    pizza_form = PizzaFormSet(request.POST or None)

    return render(request, "place_order.html", {
        'restaraunt': restaraunt,
        'pizza_form': pizza_form,
    })

如果这些实际上没有运行,请不要打我太多。就像我说的那样,由于各种原因我不能在这里发布真实代码,部分原因是它太大了。

为了这个例子,假设这个人已经找到离他们家最近的餐馆并开始订购过程。

我曾尝试将小部件传递给具有正确名称和选项的 modelformset_factory,但没有传播。

widgets = {'toppings': 
    CheckboxSelectMultiple(
        choices=[t.id for t in restaraunt.toppings.all().order_by('-id')]
    )}

我还尝试扩展 BaseModelFormSet 以传递额外数据并尝试将其放入 PizzaForm 但我卡住了。

基本上我可以说我需要以某种方式将信息从 View 传播到表单集再到表单,以便可以正确初始化表单上的查询集。我只是不知道该怎么做。

所以这是我找到的最接近答案的答案,但我似乎无法弄清楚如何确保它有效: Django filter ModelFormSet field choices... different from limiting the Formset's queryset

回应那些因为发布了一个无法工作的例子而缠着我的人

要点是,我并不是要要求某人发布将完全解决我的问题的确切 10 行代码,而是要展示我缺乏知识的地方。我知道我生成了一个 PizzaFormSet,并且最终在该代码的某个地方使用了我指定的 PizzaForm。但是我不知道如何成功地将信息从 PizzaFormSet 传递到 PizzaForm。

基本上,如果有人提出我遗漏了这个难题的哪一部分的建议,我愿意悬赏。

问题出在哪里

我在 forms.py (PizzaForm) 中定义了一个表单,它需要为 Topping 获取一个依赖于情境的查询集。 View order_pizzas 确定哪家餐厅将制作和交付比萨饼,并且该餐厅提供的配料可能与其他餐厅不同。

我不知道如何将该信息从 View 传播到表单,通常您只需将表单子(monad)类化并添加一些额外的 init kwargs 来做任何您想做的事情。

但在这种情况下,我使用的是表单集而不是单个表单。这意味着我必须找到(或建立)一些 channel 来将餐厅信息和/或特定查询集从 View 传递到表单集再到表单。我认为这是我的主要困惑和/或无知点。

最佳答案

这是一个解决方案。可能有更好的,但这应该有效。遍历表单集中的所有表单,并更改 toppings 字段中的 choices 变量。像这样:

pizza_form = PizzaFormSet(request.POST or None)

choices = [(t.pk, unicode(t)) for t in restaraunt.toppings.all().order_by('-id')]

for form in pizza_form:
    form.fields['toppings'].choices = choices

您还可以覆盖 BaseModelFormset 并覆盖 _contruct_forms 方法,将 restaraunt 对象传递给表单的 __init__,然后更改浇头的那里的选择。但我认为上述解决方案是最快和最简单的。它只是引入了一个额外的循环。

关于python - 如何过滤django modelformset manytomany成员的查询集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22390343/

相关文章:

Python 文件写入在 Windows 上有效,但在 Linux 上无效

python - 使用 cx_freeze 卡住的 pyGTK 应用程序看起来有所不同

python - Django 管理站点 -- 查看路径 "admin/"at "/"

django - Django表单中的空ChoiceField选择

django - 在 django-crispy 按钮名称中使用 django 模板变量

django - 将未绑定(bind)的表单转换为绑定(bind)的表单?

python - 如何在 python 中使用 if 语句对扩展列表执行求和?

python - 通过蓝牙将 Arduino 连接到 Python

Django 和 bootstrap navbar - 区分当前页面的链接

Python追加: It only return the last value repeatedly