我可以't use the proper code but I found the pizza/toppings question and it'关闭所以我正在修改它来问我的问题 . Django ModelForm for Many-to-Many fields
我们有Pizza和Topping很棒 . 让我们说我们经营一系列商店,并非所有商店都有所有成分 . 这意味着我们需要一个Store类,它具有一个位置,并且有许多用于浇头 . 然后让我们推出一个引用商店的订单,并且因为您经常订购不止一个,所以在Pizza上有很多 .
models.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)
forms.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()
)
views.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,但我遇到了困难 .
基本上我可以告诉我,我需要以某种方式将信息从视图传播到formset到表单,以便可以正确初始化表单上的查询集 . 我只是无法弄清楚如何做到这一点 .
所以这是我最接近的似乎是如何确保如此工作:Django filter ModelFormSet field choices... different from limiting the Formset's queryset
回应那些想要发布一个非工作示例的人
关键是我不是要求某人发布完全解决我的问题的确切的10行代码,而是我正在展示我的知识缺乏的地方 . 我知道我生成了一个PizzaFormSet,并最终在该代码的内部某处使用我指定的PizzaForm . 但我不知道如何成功地将信息从PizzaFormSet传递到PizzaForm .
基本上我愿意放弃赏金,以获得关于这个难题的哪些部分我缺失的建议 .
问题出在哪里
我在forms.py(PizzaForm)中定义了一个表单,它需要为Topping获取一个依赖于情境的查询集 . 视图order_pizzas决定了哪个餐厅将制作和提供比萨饼,并且该餐厅提供的配料可能与其他餐厅不同 .
我不知道如何将视图中的信息传播到表单,通常你只是将表单子类化并添加一些额外的init kwargs来做任何你想做的事情 .
但在这种情况下,我使用的是formset而不是单一的形式 . 这意味着我必须找到(或制作)一些 Channels 将餐馆信息和/或特定查询集从视图传递到表单到表单 . 我认为这是我的主要困惑和/或无知 .
2 回答
这是一个解决方案 . 可能有一个更好的,但这应该工作 . 循环遍历formset中的所有表单,并更改
toppings
字段上的choices
变量 . 像这样:你也可以覆盖
BaseModelFormset
并覆盖_contruct_forms
方法,将restaraunt对象传递给表单的__init__
,然后在那里更改顶部的选择 . 但我认为上述解决方案是最快捷,最简单的 . 它只是引入了一个额外的循环 .你可以有一个制作PizzaForms的工厂:
并在您的视图中使用它:
也许你的模型有一个限制,以确保你可以使用
pizzaform_factory
(即使用管理员,shell脚本或API调用),你仍然可以得到无法填充的订单 .