如何过滤Django modelformset manytomy memeb的queryset

2024-10-01 00:21:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我不能使用正确的代码,但我发现了比萨饼/浇头问题,它很接近,所以我修改它来问我的问题。Django ModelForm for Many-to-Many fields

我们有很棒的披萨和配料。假设我们经营一家连锁店,并不是所有的商店都有所有的原料。这意味着我们需要一个Store类,它有一个位置和一个用于浇头的many-many。然后,让我们下一个订单,参考一家商店,因为你经常订一个以上的比萨饼。在

在模型.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在

^{pr2}$

在视图.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_工厂,但是没有传播。在

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

我还尝试扩展BaseModelFormSet来传递额外的数据,并尝试将其放入PizzaForm,但是我遇到了麻烦。在

基本上,我可以知道我需要以某种方式将信息从视图传播到表单集,然后将表单上的queryset正确初始化。我只是不知道该怎么做。在

因此,这是我找到的最接近答案的答案,但我似乎无法确定如何使其有效: Django filter ModelFormSet field choices... different from limiting the Formset's queryset

为了回应那些因为我贴了一个不起作用的例子而纠缠我的人

关键是,我并不是要找人来发布能完全解决我问题的10行代码,而是我在展示我所缺乏的知识。我知道我生成了一个PizzaFormSet,最终在代码内部的某个地方,它使用了我指定的PizzaForm。但我不知道如何成功地将信息从PizzaFormSet传递到PizzaForm。在

基本上,我愿意给一个建议,关于这个难题我错过了什么部分。在

问题出在哪里

我在中定义了一个窗体表单.py(PizzaForm)需要根据情况为顶部设置查询集。查看订单披萨决定哪家餐厅将制作和交付披萨,该餐厅提供的配料可能与其他餐厅不同。在

我不知道如何将这些信息从视图传播到表单,通常您只需将表单子类化并添加一些额外的init kwargs来执行任何您想要的操作。在

但在本例中,我使用的是一个表单集而不是一个表单。这意味着我必须找到(或建立)某种渠道来将餐厅信息和/或特定的查询集从视图传递到表单集再传递到表单。我想这就是我困惑和/或无知的主要原因。在


Tags: django代码frompyimportid表单model
2条回答

这里有一个解决方案。也许还有更好的办法,但这应该行得通。循环检查formset中的所有表单,并更改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__,然后在那里更改topping的选择。但我认为上述解决方案是最快和最简单的。它只是引入了一个额外的循环。在

你可以有一家生产披萨的工厂:

def pizzaform_factory(restaurant):
    class PizzaForm(ModelForm):

        class Meta:
            model = Pizza

        toppings = forms.ModelMultipleChoiceField(
            widget=forms.CheckboxSelectMultiple(),
            queryset=restaurant.toppings.all()
        )
    return PizzaForm

并在您的视图中使用它:

^{pr2}$

也许限制你的模型,以确保你不能创造不可能的订单。{end}如果你仍然不能使用一个命令,就不能使用命令。在

相关问题 更多 >