Django M2M Form



我尝试在M2M字段的形式做复选框,但有这个错误,不知道如何修复它。谷歌没有帮我,我试过了。

当我渲染对象作为列表时,我可以选择几个对象并保存它,所以问题不在views.py中,但它不适用于复选框。

我代码:

forms.py

class CheckoutForm(forms.ModelForm):
class Meta:
model = Checkout
fields = ('dishes', 'user')
def __init__(self, *args, **kwargs):
super(CheckoutForm, self).__init__(*args, **kwargs)
self.fields["dishes"].widget = CheckboxSelectMultiple()
self.fields["dishes"].queryset = Dish.objects.all()

所以我只能看到一个表单错误:

呈现表单字段-发送一个空表单-放回{{表单。As_p}} -我可以看到一个错误"字段是必需的">

page.html

<form class="p-2" action="{% url 'make_order' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<select name="user">
<option value="{{ user.id }}">{{ user }}</option>
</select>
<div
class="row row-cols-1 row-cols-md-5 g-2"
style="margin-left: -40px"
>
{% for dish in dishes %}
<div class="col">
<div class="card" style="width: 14rem">
<img
class="card-img-top"
style="width: 220px; height: 240px"
src="{{ dish.image.url }}"
alt="Card image cap"
/>
<div class="card-body">
<h5 class="card-title">{{ dish.name }}</h5>
<p class="card-text">Description: {{ dish.description }}</p>
<p class="card-text">Ingredients: {{ dish.ingredients }} g</p>
<p class="card-text">Serving size: {{ dish.serving_size }} g</p>
<p class="card-text">Price: {{ dish.price }} UAH</p>
<input
type="checkbox"
class="btn btn-primary"
name="dishes"
id="{{ dish.id }}"
value="{{ dish.id }}"
/>Add to cart
</div>
</div>
</div>
{% endfor %}
<input type="submit" value="ADD" class="btn btn-primary" />
</form>

views.py

class OrderView(LoginRequiredMixin, CreateView):
model = Checkout
template_name = "food_order/make_order.html"
form_class = CheckoutForm
success_url = "/order/"
login_url = "/login/"
raise_exception = True
def form_valid(self, form):
print('i am here')
instance = form.save(commit=False)
instance.user = self.request.user
instance.save()
dishes = form.cleaned_data["dishes"]
for dish in dishes:
dish, created = Dish.objects.get_or_create(name = dish)
dish.save()
instance.dishes.add(dish)
instance.save()
print(instance.dishes)
print(instance)
form.save_m2m()
return super(OrderView, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(OrderView, self).get_context_data(**kwargs)
context["dishes"] = Dish.objects.all()
context["orders"] = Checkout.objects.all()
return context

我认为在设置小部件时不需要在这里修改__init__。它可能会覆盖modelform的值。

试题:

class CheckoutForm(forms.ModelForm):
class Meta:
model = Checkout
fields = ('dishes', 'user',)
widgets = {'dishes': forms.CheckboxSelectMultiple() }

这应该工作,因为m2m字段默认具有modelmultiechoicefield。如果你想让它显式,你可以这样做:

class CheckoutForm(forms.ModelForm):
dishes = forms.ModelMultipleChoiceField(
queryset=Dish.objects.all(),
widget=forms.CheckboxSelectMultiple,
)
class Meta:
model = Checkout
fields = ('dishes', 'user',)

手动设置复选框格式

确保它们有name="dishes"(假设dishes是您的Checkout模型中的字段名称)和value="<the dish id>"

你可能还需要用request.POST.getList('dishes')抓取提交的值,否则你只会得到一个提交的值

最新更新