2015-11-09 69 views
1

我的合作伙伴不同意我關於Django的一個常見的情況。Django的方式:ForeignKey的或多對多?

我的觀點(4個明確的表,1 JOIN得到角色):

class Guest(models.Model): 
    creation_date = models.DateTimeField(auto_now_add=True) 
    email   = models.EmailField(max_length=255) 

class GuestRole(models.Model): 
    TYPE_CHOICES = (
    (1, 'Administrator'), 
    (2, 'Assistant'), 
    (3, 'Technician'), 
) 
    guest = models.ForeignKey('Guest', null=True, related_name='roles') 
    type = models.PositiveSmallIntegerField(null=True, choices=TYPE_CHOICES) 


class User(models.Model): 
    creation_date = models.DateTimeField(auto_now_add=True) 
    email   = models.EmailField(max_length=255, unique=True) 

class UserRole(models.Model): 
    TYPE_CHOICES = (
    (1, 'Administrator'), 
    (2, 'Assistant'), 
    (3, 'Technician'), 
) 

    user = models.ForeignKey('User', null=True, related_name='roles') 
    type = models.PositiveSmallIntegerField(null=True, choices=TYPE_CHOICES) 

他的觀點(3個明確的表+ 2個隱藏的表,2 JOIN得到角色):

class Guest(models.Model): 
    creation_date = models.DateTimeField(auto_now_add=True) 
    email   = models.EmailField(max_length=255) 
    role   = models.ManyToMany('Role') 

class User(models.Model): 
    creation_date = models.DateTimeField(auto_now_add=True) 
    email   = models.EmailField(max_length=255, unique=True) 
    role   = models.ManyToMany('Role') 

class Role(models.Model): 
    label = models.CharField(max_length=20) 

(A客戶是由用戶邀請,併成爲用戶如果他接受了邀請)

反正,什麼是Django的方式適合你?

回答

0

我有更好的想法:

class RoleInfo(models.Model): 
    TYPE_CHOICES = (
    (1, 'Administrator'), 
    (2, 'Assistant'), 
    (3, 'Technician'), 
) 
    type = models.PositiveSmallIntegerField(null=True, choices=TYPE_CHOICES) 
    creation_date = models.DateTimeField(auto_now_add=True) 

    class Meta: 
    abstract = True 

class Guest(RoleInfo): 
    email = models.EmailField(max_length=255) 

class User(RoleInfo): 
    email = models.EmailField(max_length=255, unique=True) 

基本上,你的第一個例子是OK,但你使用相同的代碼兩次。你的第二個例子是像我寫的,但有點差,你會在你的數據庫創建一個Role表並創建Role類也實例,這是你真正想要的是什麼?

如果你想使用同一段代碼在很多的模型,你可以使用抽象類或代理類。當你需要一個新的字段添加到一個抽象的模型您GuestUser創造是最好的變種。

More about abstract models.

+0

抽象類是現場的重複數據刪除,但在你的例子一個很好的選擇,我只能有一個爲每個用戶/客串角色,不是嗎?所以它和我的例子不完全一樣。所以你認爲代碼重複數據刪除(manyToMany)比查詢優化(ForeignKey)更好? – frlinw

+0

@frlinw如果你想有機會做出一些關係比較複雜的角色,你可以看看[Django的權限模型(https://github.com/django/django/blob/15ef1dd478c5b6f005e5f782b7619f718ed55e84/django/contrib/auth/models .py#L207),因爲它幾乎與你的'Role'類相同。他們使用一個m2m關係的mixin與一個「Permision」模型。 – pythad