首页 > 解决方案 > 只允许在 Django 模型和管理员中填写一个或另一个字段

问题描述

我有一个简单的 Django 模型,用于一个包含联系人列表的Group。每个组必须选择主要联系人所有联系人,但不能同时选择两者,也不能没有。 ForeignKey BooleanField

class Group(models.Model):
    contacts = models.ManyToManyField(Contact)
    contact_primary = models.ForeignKey(Contact, related_name="contact_primary", null=True)
    all_contacts = models.BooleanField(null=True)

我怎样才能确保:

  1. contact_primary除非设置了其中一个或all_contacts(但不是两者),否则无法保存模型。我想这将是通过实现该Group.save()方法?还是应该是Group.clean()方法??

  2. 在 Django Admin 中,要么在选择一个字段时禁用另一个字段,要么至少提供一个有意义的错误消息,如果两者都设置或没有设置并且管理员尝试保存它?

谢谢!

标签: djangodjango-admin

解决方案


最简单的方法是覆盖save()模型的方法:

class Group(models.Model):
    contacts = models.ManyToManyField(Contact)
    contact_primary = models.ForeignKey(Contact, related_name="contact_primary", blank=True, null=True)
    all_contacts = models.BooleanField(blank=True, null=True)

    def save(self, *args, **kwargs):
        if self.contact_primary is not None and self.all_contacts is not None:
            raise Exception("some error message here")  
        if self.contact_primary is None and self.all_contacts is None:
            raise Exception("some other error message here")  

        return super().save()

请注意,我已添加blank=True到您的模型字段中。如果您想通过管理员或表单插入空列,这是必要的。

更新

如果要提高 a ValidationError,则必须从模型的clean()方法中提高它。否则,您将给客户端一个 500 错误,而不是错误消息。


推荐阅读