gpt4 book ai didi

python - 在 django admin 中验证依赖内联

转载 作者:太空狗 更新时间:2023-10-29 17:14:42 28 4
gpt4 key购买 nike

我正在使用 Django 1.4,我想设置验证规则来比较不同内联的值。

我有三个简单的类

在 models.py 中:

class Shopping(models.Model):
shop_name = models.CharField(max_length=200)

class Item(models.Model):
item_name = models.CharField(max_length=200)
cost = models.IntegerField()
item_shop = models.ForeignKey(Shopping)

class Buyer(models.Model):
buyer_name = models.CharField(max_length=200)
amount = models.IntegerField()
buyer_shop = models.ForeignKey(Shopping)

在 admin.py 中:

class ItemInline(admin.TabularInline):
model = Item

class BuyerInline(admin.TabularInline):
model = Buyer

class ShoppingAdmin(admin.ModelAdmin):
inlines = (ItemInline, BuyerInline)

例如,可以 10 美元购买一瓶朗姆酒,8 美元购买一瓶伏特加。迈克支付 15 美元,汤姆支付 3 美元。

目标是防止用户保存金额不匹配的实例:已支付的金额必须与项目成本的总和相同(即 10+8 = 15+3)。

我试过:

  • 在 Shopping.clean 方法中引发 ValidationError。但是内联还没有干净地更新,所以总和不正确
  • 在 ShoppingAdmin.save_related 方法中引发 ValidationError。但是在这里引发 ValidationError 会提供一个对用户非常不友好的错误页面,而不是重定向到带有漂亮错误消息的更改页面。

这个问题有什么解决办法吗?客户端(javascript/ajax)验证是最简单的吗?

最佳答案

您可以覆盖您的内联表单集来实现您想要的。在 formset 的干净方法中,您可以通过“实例”成员访问您的购物实例。因此,您可以使用 Shopping 模型临时存储计算出的总数并使您的表单集相互通信。在 models.py 中:

class Shopping(models.Model):
shop_name = models.CharField(max_length=200)

def __init__(self, *args, **kwargs)
super(Shopping, self).__init__(*args, **kwargs)
self.__total__ = None

在 admin.py 中:

from django.forms.models import BaseInlineFormSet
class ItemInlineFormSet(BaseInlineFormSet):
def clean(self):
super(ItemInlineFormSet, self).clean()
total = 0
for form in self.forms:
if not form.is_valid():
return #other errors exist, so don't bother
if form.cleaned_data and not form.cleaned_data.get('DELETE'):
total += form.cleaned_data['cost']
self.instance.__total__ = total


class BuyerInlineFormSet(BaseInlineFormSet):
def clean(self):
super(BuyerInlineFormSet, self).clean()
total = 0
for form in self.forms:
if not form.is_valid():
return #other errors exist, so don't bother
if form.cleaned_data and not form.cleaned_data.get('DELETE'):
total += form.cleaned_data['cost']

#compare only if Item inline forms were clean as well
if self.instance.__total__ is not None and self.instance.__total__ != total:
raise ValidationError('Oops!')

class ItemInline(admin.TabularInline):
model = Item
formset = ItemInlineFormSet

class BuyerInline(admin.TabularInline):
model = Buyer
formset = BuyerInlineFormSet

这是唯一可以做到这一点的干净方式(据我所知),所有东西都放在它应该在的地方。

编辑: 添加了 *if form.cleaned_data* 检查,因为表单也包含空内联。请告诉我这对您有何帮助!

EDIT2:添加了对即将删除的表单的检查,正如评论中正确指出的那样。这些表格不应参与计算。

关于python - 在 django admin 中验证依赖内联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13526792/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com