Django 模型继承与 OneToOne 字段

Django Model Inheritance versus OneToOne field

编辑:两种方法的优点和缺点。 所以, 我有三个模型:人、客户、成员 Person 是基本模型,Client 和 Member 是 Person 的配置文件。

class Person(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(
        verbose_name=_('email address'),
        max_length=255,
        unique=True,
    )

class Client(User): #or maybe models.Model and explicit OneToField 
    first_name = models.CharField(verbose_name=_('first name'), max_length=30)
    last_name = models.CharField(verbose_name=_('last name'), max_length=30)

class Member(User): #or maybe models.Model and explicit OneToField 
    description = models.CharField(verbose_name=_('first name'), max_length=255)
   # other stuff

那么,我想要什么?

  1. 在管理员中,当我们添加客户或成员时,我想填写电子邮件字段(来自基础 class 的字段),就好像它在派生 class 中一样。例如,在管理中 list_display = ('email', 'first_name')。不是 select 个用户框。

  2. Person class 可以单独实例化,"attached" 到创建的配置文件。比如person=Person(email="test@gmail.com"), client=Client(person=person,first_name="test"...)。特别是,这应该以表格形式工作。当用户(人)通过身份验证时,我想提供填写个人资料(客户)表格并将人员附加到此表格的能力。

  3. 一个人可以同时拥有两个账户。如果我删除client/member,对应的人应该不会被删除

第三个选项其实不是必须的,但知道怎么做对我很有用。

所以,方案一是通过继承完美解决的,Person就是User,但是当方案二实现时,这种方式就失效了。由于PersonClient被认为是一个整体,我无法附加用户,重复键错误。

选项 2 通过扩展 models.Model 并附加 person=models.OnetoOneField(Person,primary_key=True) 解决。但是,管理员坏了(第一个选项),因为客户端没有像电子邮件这样的字段。

那么,要采取什么方法来解决以上问题呢? 有没有简单的方法? 如果没有简单的方法,是否有高级方法,如重写元class、对象描述符或编写自定义 OneToOne 字段?

欢迎提出任何建议。

谢谢。

您可以为此使用 post_delete signal

所以你会:

  • 在两个模型上注册 post_delete 信号
  • 一个删除,检查另一个对象是否存在,然后删除。

Whosebug 上有很多关于 post_delete 信号实现的示例,所以我将省略该部分。