2013-08-31 2 views
2

У меня есть три модели классов:Объединяя абстрактный класс модели и наследование нескольких таблиц в Django

django.contrib.auth.models.User, обозначаемые как User

mysite.models.Profile, обозначаемый как Profile

mysite.models.Subscriber, обозначаемый как Subscriber

Profile наследует от User таким образом, который является well described в документах как решение для добавления настраиваемых свойств к модели User без проблем с моделями с возможностью замены (которые были добавлены только в версии 1.5).

В то время как Profile и Subscriber - это разные объекты, они действительно обладают некоторыми свойствами. А именно, я хочу использовать собственный алгоритм первичного ключа с обоим и переопределить метод save() аналогичным образом, чтобы код можно было повторно использовать в соответствии с DRY. Теперь, если бы оба были обычными образцовыми классами, это было бы просто:

class BaseProfile(models.Model): 
    key = models.PositiveIntegerField(primary_key=True) 
    activated = models.BooleanField(default=False) 
    ... 

    class Meta: 
     abstract = True 

    def save(): 
     ... 

class Profile(BaseProfile): 
    ... 

class Subscriber(BaseProfile): 
    ... 

Однако профиль уже использует наследование с несколькими таблицами. Я думаю о том, как это делается:

class BaseProfile(models.Model): 
    key = models.PositiveIntegerField(primary_key=True) 
    activated = models.BooleanField(default=False) 
    ... 

    class Meta: 
     abstract = True 

    def save(): 
     ... 

class Profile(BaseProfile, User): 
    user = models.OneToOneField(User, parent_link=True, blank=True, null=True, on_delete=models.CASCADE) 
    ... 

class Subscriber(BaseProfile): 
    ... 

Возможно ли это? Если да, то какой порядок наследования необходим в моем случае, так что оба поля модели и метод save() вызываются правильным образом? Будет ли Meta обоих модельных классов не конфликтовать?

ответ

2

В документации, на которую вы ссылаетесь, не описывается наследование от пользователя через наследование с несколькими столами. Это объясняет, что вы можете связать объект с профилем, используя OneToOneField. Попытайтесь:

class Profile(BaseProfile): 
    user = models.OneToOneField(User, blank=True, null=True, on_delete=models.CASCADE) 
    ... 

Я подозреваю, что вы действительно не хотите пусто = True и null = Правда там.

Этот подход означает, что объекты вашего пользователя, скорее всего, не будут иметь одинаковые первичные ключи, как их соответствующие объекты профиля, но это может быть хорошо для вас.

+0

Да, это нормально и нет, я хочу пусто = True и null = True :) То, что я хотел, это поля пользователя, доступные для объектов Profile, но похоже, что это не соответствует абстрактным классам моделей, поэтому я прибегаю к этому решению. – Red

Смежные вопросы