在Django中,如何在任何验证发生之前计算或更新某些模型字段?

时间:2012-11-30 16:20:47

标签: django

所以我是Django的新手......

首先介绍一下我们现在如何做事的背景。我们有一个自定义的PHP系统,但我只使用管理界面在django中构建一个改进的库存管理系统。我们存储部件号,并且必须不存储重复。有时可以使用超大,期间,空格等输入部件号。无论输入何种格式,我们都需要确保不会添加重复部件。使用我们现有的非django系统,我们使用正则表达式从不是a-zA-Z0-9的字符串中去除任何东西。实际输入的部件号是持久的,清理后的号码也会持久保存到数据库中。然后,当有人添加新零件或甚至搜索零件时,此零件号的清洁版本有助于避免这种模糊性。我们对制造商名称也这样做。

我在django中模拟这个的方法是将part_number_clean字段和part_number字段添加到模型中。然后我覆盖了save方法来计算干净的部件号,如此(制造商也是):

def save(self, *args, **kwargs):
    self.manufacturer_clean = re.sub(r'[^a-zA-Z0-9]', '', self.manufacturer).lower()
    self.part_number_clean = re.sub(r'[^a-zA-Z0-9]', '', self.part_number).lower()
    super(CatalogProduct, self).save(*args, **kwargs) 

问题是,我需要在零件编号和制造商的组合上独一无二:

class Meta:
    unique_together     = ('part_number_clean ', 'manufacturer_clean ')

当我尝试保存重复记录时,我收到了数据库完整性违规。所以似乎django在调用save函数之前正在评估唯一字段(这很有意义)。我只需要知道在任何验证之前我应该​​如何或哪种方法来计算这些字段。

此外,我有兴趣在unique_together混音中添加第三个字段,可以填写也可以不填写。如果未填充,则只有一个空的默认值。我希望这不会引起任何问题。

如果当用户选中制造商和零件编号字段并且两者都不为空时,一些js将看到该产品是否已存在,并且为用户提供单击按钮的选项,这也是很好的。在他们浪费时间填写剩下的数据之前,才发现它已经存在。我猜这是在管理界面的范围之外没有严重的黑客攻击。有没有办法以某种方式将其与管理界面集成?到目前为止它对我很有用......

2 个答案:

答案 0 :(得分:4)

我明白了。我正在为其他任何好奇的人发布答案。实际上,这在模型中实现起来非常简单。所有人需要做的是实现(覆盖?)模型的clean()方法。在方法中,我计算并设置我的特殊字段,然后一定要调用self.validate_unique()。奇迹般有效!无需提出任何异常,表单将完美地显示错误。在save方法中执行此操作将不起作用,因为此时您的代码或django不能抛出异常。这是代码:

class CatalogProduct(models.Model):
    manufacturer        = models.CharField(max_length=100)
    manufacturer_clean  = models.CharField('Manufacturer',max_length=100,blank=True,editable=False)
    part_number         = models.CharField(max_length=100)
    part_number_clean   = models.CharField('Part number',max_length=100,blank=True,editable=False)

    def clean(self):
        # Calculate manufacturer_clean and part_number_clean
        self.manufacturer_clean = re.sub(r'[^a-zA-Z0-9]', '', self.manufacturer).lower()
        self.part_number_clean = re.sub(r'[^a-zA-Z0-9]', '', self.part_number).lower()
        self.validate_unique()

答案 1 :(得分:0)

该模型仅负责描述数据以及如何在Python和数据库环境之间表示数据。正是由于这个原子角色,模型不关心验证以及你刚刚进入并引入它的内容。

您需要一个模型表单。它可以清洁制造商和部件号,并确保在验证过程中满足唯一性约束。