Django多表继承VS在模型中指定明确的一对一关系 [英] Django Multi-Table Inheritance VS Specifying Explicit OneToOne Relationship in Models

查看:131
本文介绍了Django多表继承VS在模型中指定明确的一对一关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

希望所有这些都是有道理的:)如有必要,我将通过评论进行澄清。另外,我正在尝试在此问题中使用粗体字,如果我(或您)发现它会分散注意力,则会对其进行编辑。

Hope all this makes sense :) I'll clarify via comments if necessary. Also, I am experimenting using bold text in this question, and will edit it out if I (or you) find it distracting. With that out of the way...

使用django.contrib.auth为我们提供了User和Group,以及其他我不能缺少的有用功能(例如基本功能)

Using django.contrib.auth gives us User and Group, among other useful things that I can't do without (like basic messaging).

在我的应用中,我有几种不同类型的用户。用户只能是一种类型。这一点很容易由团体来解决,而无需多加注意。 但是,这些不同的用户在层次结构/关系中彼此相关。

In my app I have several different types of users. A user can be of only one type. That would easily be handled by groups, with a little extra care. However, these different users are related to each other in hierarchies / relationships.

让我们看看这些用户:-

Let's take a look at these users: -

主体-顶级用户

管理员-每个管理员都向负责人

协调员-每个协调员都向管理员报告

除了这些,还有其他用户类型不直接相关,但稍后可能会相关。例如,公司是另一种类型的用户,可以具有各种产品,并且产品可以由协调员监督。 买方是另一种可能会购买产品的用户。

Apart from these there are other user types that are not directly related, but may get related later on. For example, "Company" is another type of user, and can have various "Products", and products may be supervised by a "Coordinator". "Buyer" is another kind of user that may buy products.

现在,所有这些用户都具有其他各种属性,其中某些属性对于所有类型的用户都是通用的其中有些仅针对一种用户类型。例如,所有类型的用户都必须有一个地址。另一方面,只有主要用户属于 BranchOffice。

Now all these users have various other attributes, some of which are common to all types of users and some of which are distinct only to one user type. For example, all types of users have to have an address. On the other hand, only the Principal user belongs to a "BranchOffice".

上面提到的另一点是,用户只能

Another point, which was stated above, is that a User can only ever be of one type.

该应用还需要跟踪谁创建和/或修改了负责人,管理员,协调员,公司,产品等。 。 (因此,还有两个到User模型的链接。)

The app also needs to keep track of who created and/or modified Principals, Administrators, Coordinators, Companies, Products etc. (So that's two more links to the User model.)

在这种情况下,使用Django的多表继承是一个好主意,如下所示:-

In this scenario, is it a good idea to use Django's multi-table inheritance as follows: -

from django.contrib.auth.models import User
class Principal(User):
    #
    #
    #    
    branchoffice = models.ForeignKey(BranchOffice)
    landline = models.CharField(blank=True, max_length=20)    
    mobile = models.CharField(blank=True, max_length=20)
    created_by = models.ForeignKey(User, editable=False, blank=True, related_name="principalcreator")    
    modified_by = models.ForeignKey(User, editable=False, blank=True, related_name="principalmodifier")
    #
    #
    #

还是我应该像这样去做:-

Or should I go about doing it like this: -

class Principal(models.Model):
    #
    #
    #
    user = models.OneToOneField(User, blank=True)
    branchoffice = models.ForeignKey(BranchOffice)
    landline = models.CharField(blank=True, max_length=20)    
    mobile = models.CharField(blank=True, max_length=20)
    created_by = models.ForeignKey(User, editable=False, blank=True, related_name="principalcreator")    
    modified_by = models.ForeignKey(User, editable=False, blank=True, related_name="principalmodifier")
    #
    #
    #

请记住,还有其他通过外键关联的用户类型,例如:-

Please keep in mind that there are other user types that are related via foreign keys, for example: -

class Administrator(models.Model):
    #
    #
    #
    principal = models.ForeignKey(Principal, help_text="The supervising principal for this Administrator")
    user = models.OneToOneField(User, blank=True)
    province = models.ForeignKey(         Province)
    landline = models.CharField(blank=True, max_length=20)    
    mobile = models.CharField(blank=True, max_length=20)
    created_by = models.ForeignKey(User, editable=False, blank=True, related_name="administratorcreator")    
    modified_by = models.ForeignKey(User, editable=False, blank=True, related_name="administratormodifier")

我知道Django确实在幕后使用一对一关系进行多表继承。我只是没有足够的资格来决定哪种方法更合理。

I am aware that Django does use a one-to-one relationship for multi-table inheritance behind the scenes. I am just not qualified enough to decide which is a more sound approach.

推荐答案

我想通过@thornomad。

I'd like to expand on the solution by @thornomad.

直接扩展Django的User类会引起内部django.auth机制的种种麻烦。在类似情况下,我所做的正是@thornomad的建议-我制作了自己的UserProfile模型与Django User模型一对一链接,其中保存了额外的用户数据,并从中继承了不同类型的模型的用户。

Extending Django's User class directly can cause all kinds of trouble with the internal django.auth mechanisms. What I've done in a similar situation is precisely what @thornomad suggests - I made my own UserProfile model linked one-to-one with the Django User model, in which I held additional user data and from which I inherited models for different types of users.

符合您所描述的内容:

class UserProfile(models.Model):
    user = models.OneToOneField(User, blank=True, related_name='profile')
    class Meta:
        abstract = True


class PositionHolderUserProfile(UserProfile):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    landline = models.CharField(blank=True, max_length=20)    
    mobile = models.CharField(blank=True, max_length=20)
    created_by = models.ForeignKey(PositionHolderUserProfile, editable=False, blank=True, related_name="created_users")    
    modified_by = models.ForeignKey(PositionHolderUserProfile, editable=False, blank=True, related_name="modified_users")

class Principal(PositionHolderUserProfile):
    branchoffice = models.ForeignKey(BranchOffice)

class Administrator(PositionHolderUserProfile):
    superior = models.ForeignKey(Principal, related_name="subordinates")
    province = models.ForeignKey(Province)

class Coordinator(PositionHolderUserProfile):
    superior = models.ForeignKey(Administrator, related_name="subordinates")


class Company(UserProfile):
    name = models.CharField(max_length=50)

class Product(models.Model):
    name = models.CharField(max_length=50)
    produced_by = models.ForeignKey(Company)

class Buyer(UserProfile):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    products_bought = models.ManyToManyField(Product)

这篇关于Django多表继承VS在模型中指定明确的一对一关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆