使用ManyToManyField在Django模型上覆盖保存方法的问题

时间:2016-11-11 22:11:14

标签: django django-models django-admin

我无法覆盖Django模型上的save方法来检查多对多字段的限制。

说我有以下型号:

class Person(models.Model):
    name = models.CharField()

class ClothingItem(models.Model):
    description = models.CharField()
    owner = models.ForeignKey(Person)

class Outfit(models.Model):
    name = models.CharField()
    owner = models.ForeignKey(Person)
    clothing_items = models.ManyToManyField(ClothingItem)

我想对save Outfit方法施加限制,以确保给定装备中的每个ClothingItemOutfit本身具有相同的所有者。

即。我想写:

class Outfit(models.Model):
    name = models.CharField()
    owner = models.ForeignKey(Person)
    clothing_items = models.ManyToManyField(ClothingItem)

    def save(self, *args, **kwargs):
        for ci in self.clothing_items:
            if ci.owner != self.owner:
                raise ValueError('You can only put your own items in an outfit!)
        super(Outfit, self).save(*args, **kwargs)

但是当我尝试时,我收到有关<Outfit: SundayBest>" needs to have a value for field "outfit" before this many-to-many relationship can be used.

的错误消息

任何想法在这里出了什么问题?

1 个答案:

答案 0 :(得分:2)

这里有两个问题。要直接回答您的问题,错误基本上意味着:如果原始对象(此处first的实例)未保存在数据库中,则无法引用任何m2m关系。

听起来你正试图在collect方法中进行验证,这在django中是一个非常糟糕的做法。验证过程通常应在创建Outfit个对象的save()中进行。要覆盖默认的django表单,请参阅django ModelAdmin.form。要了解如何对django表单进行验证,请检查ModelForm validation

如果您想要代码参考m2m验证,我找到了good example from SO