我正在建立一个旨在提供食物的网站。我有一个代表餐的模型“ Plat”和一个代表命令的模型“ Commande”。在网站上,用户可以看一顿饭,然后单击“下订单”按钮,最后用订单详细信息填写表格。 “ Commande”具有多个字段,其中之一是“ plat”,可将订单链接到餐点。我的问题是,在呈现表单之前,我需要填写“ Commande”模型的“ plat”字段,因为我有一个取决于“ Plat”模型的字段的验证规则:在“ Commande”表单中,客户可以选择他想要的一餐饭的份数,如果此份数大于可用份数(parts_available是“ Plat”文件),则会引发错误。
我尝试过这种方式(请参见下文),但这种方法不起作用,当客户保存“ Commande”表单时,它会引发AttributeError,因为它尝试访问plat的字段但plat等于没有。你知道我该怎么做吗?
谢谢!
models.py
class Plat(models.Model):
SOME FIELDS
nb_portions = models.IntegerField(verbose_name = "Nombre de portions disponibles") # the number of parts available
class Commande(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
plat = models.ForeignKey('Plat', on_delete = models.CASCADE) # models.PROTECT pour pas supprimer, models.CASCADE pour supprimer.
nb_portions = models.IntegerField(verbose_name = "Nombre de portions")
forms.py
class CommandeForm(forms.ModelForm):
class Meta:
model = Commande
fields = ['nb_portions', 'adresse_livraison']
widgets = {'nb_portions': forms.NumberInput(attrs={'class': 'form-control'}),
'adresse_livraison': forms.TextInput(attrs={'class': 'form-control'})}
labels = {'adresse_livraison': 'Adresse de livraison (livraison à partir de 5 portions) :'}
def clean(self):
cleaned_data = super(CommandeForm, self).clean()
plat = cleaned_data.get('plat')
nb_portions = cleaned_data.get('nb_portions')
if nb_portions > plat.nb_portions:
self.add_error("Le nombre de portions maximales disponibles pour ce plat est : " + str(plat.nb_portions) + " portions.")
return cleaned_data
views.py
def commander(request, id):
plat = get_object_or_404(Plat, id=id)
if request.method == "POST":
form = CommandeForm(request.POST)
if form.is_valid():
commande = form.save(commit = False)
commande.user = request.user
commande.plat = plat
commande.save()
return redirect(commande_validee)
else:
commande = CommandeForm()
commande.plat = plat
form = commande
return render(request, 'actualites/commander.html', locals())
编辑:
我已经复制了dirkgroten在CommandeForm中建议的 init 方法,并相应地修改了视图:
def commander(request, id):
plat = get_object_or_404(Plat, id=id)
if request.method == "POST":
form = CommandeForm(request.POST, plat=plat)
if form.is_valid():
commande = form.save(commit = False)
commande.user = request.user
commande.date = plat.date_prep
commande.save()
return redirect(commande_validee)
else:
form = CommandeForm(plat=plat)
return render(request, 'actualites/commander.html', locals())
答案 0 :(得分:1)
您表单的cleaned_data
没有属性plat
,因为它不是表单中的字段。您应该将plat
作为附加参数传递给表单的init
方法,以便以后使用:
form = CommandeForm(request.POST, plat=plat)
class CommandeForm(...):
def __init__(self, *args, **kwargs):
self.plat = kwargs.pop('plat', None)
super().__init__(*args, **kwargs)
def clean(self):
...
if self.plat and nb_portions > self.plat.nb_portions:
...