Django 模型 - 相关对象验证

Posted

技术标签:

【中文标题】Django 模型 - 相关对象验证【英文标题】:Django models - related objects validation 【发布时间】:2012-03-30 11:54:04 【问题描述】:

我想知道如何对相关对象进行验证。令我惊讶的是,我没有找到很多相关信息。

例如:

class Listing(models.Model):
   categories = models.ManyToManyField('Category')
   price_sale = models.DecimalField(max_digits=8, decimal_places=0, null=True)
   price_rent = models.DecimalField(max_digits=8, decimal_places=0, null=True)
   price_vacation = models.DecimalField(max_digits=8, decimal_places=0, null=True)

class Category(models.Model):
   value = models.CharField(max_length=32)

class Image(models.Model):
   listing = models.ForeignKey('Listing')
   image = models.ImageField(upload_to=get_file_path)
如何确保至少设置了一个category,没有 列表重复? 我如何确保如果categories 之一是'sale',则必须设置price_sale 或设置为null? 如何确保至少插入了一个image,但不多 而不是说 10 张图片?

我认为这应该在模型中完成,以防我选择输入表单以外的数据(例如解析提要),这是否正确?我尝试处理clean(),但在让我处理m2m关系等之前需要进行PK。

额外问题:为什么我会选择使用选项来限制字段,而不是通过 FK 来限制?

【问题讨论】:

【参考方案1】:

尝试显式创建您的映射表,并让您的多对多关系转到through 这个模型。由于它是一个普通的 Django 模型,您应该能够在其 clean 方法中定义大部分验证逻辑。

class Listing(models.Model):
    categories = models.ManyToManyField('Category', through='CategoryListing')
    price_sale = models.DecimalField(max_digits=8, decimal_places=0, null=True)
    price_rent = models.DecimalField(max_digits=8, decimal_places=0, null=True)
    price_vacation = models.DecimalField(max_digits=8, decimal_places=0, null=True)

class Category(models.Model):
    value = models.CharField(max_length=32)

class CategoryListing(models.Model):
    category = models.ForeignKey(Category)
    listing = models.ForeignKey(Listing)

    def clean(self):
        # validation logic

https://docs.djangoproject.com/en/1.3/topics/db/models/#intermediary-manytomany

【讨论】:

这将更多地用于验证连接表行本身而不是与listing 没有关系?我想防止在没有至少一个 m2m 关系的情况下插入 listing

以上是关于Django 模型 - 相关对象验证的主要内容,如果未能解决你的问题,请参考以下文章

相关领域的 Django 模型验证

Django REST 框架:使用相关字段创建/更新对象

在 django 中将 css 类添加到验证错误的字段

如何在客户端应用程序中使用 Django 模型进行验证和表单生成?

由 sysdate 相关日期验证器引起的合成/冗余 Django 迁移

Django 通道 JWT 身份验证