0

Я хочу создать иерархию над дизайном БД, как описано в «Основах систем баз данных» от Elmasri & Navathe.Модели Django типа наследования с несколькими столами не работают

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

Я попытался использовать абстрактное и многообразное наследование (этот последний не позволяет мне указывать OneToOneField, не знаю, где его найти в django docs).

Мой пример прямо здесь (одна таблица на класс):

'''I would like this to be abstract, because I will never instantiate it, 
but could be not if needed''' 

class Person(models.Model): 
    personId = models.IntegerField(primary_key=True) 
    name = models.CharField(max_length=45) 
    surname = models.CharField(max_length=45, blank=True) 
    email = models.CharField(max_length=45, blank=True) 
    phone = models.CharField(max_length=15, blank=True) 

    class Meta: 
     managed = False 
     db_table = 'person' 

class Alumn(Person): 
    # Maybe this one down should be OneToOne. 
    # alumnId == personId always true for the same real world guy 
    alumnId = models.ForeignKey('Person', db_column='alumnId', primary_key=True) 

    comments = models.CharField(max_length=255, blank=True) 

class Meta: 
    managed = False 
    db_table = 'alumn' 

# There are more child classes (Client, Professor, etc....) 
# but for the example this is enough 

Моя цель достижения для создания Alumn в БД только с двумя предложениями, как:

a = Alumn(personId=1,name='Joe', [...more params...] , alumnId=1, comments='Some comments') 
a.save() 

и наделенный этими две строки вставляют две строки: одну для Лица и одну для выделения. Атрибут alumnId в этом фрагменте здесь может быть опущен, потому что он всегда будет таким же, как personId (я сказал вам, как слабый объект).

Я совсем новичок в Джанго, но я посмотрел на документации и доказал некоторые вещи с абстрактным = True в лице и не преуспев теперь я думаю, что я должен возиться с инициализацией конструкторами для получения суперкласса и после этого создайте дочерний класс.

Я не знаю правильного пути выбора, но определенно хочу не изменять дизайн базы данных. Пожалуйста помоги.

Заранее спасибо.

ответ

1

Вам не нужно иметь идентификаторы в ваших моделях; Django обрабатывает его автоматически. Также вы не должны использовать случай с верблюдом. Другими словами: personId должен быть person_id и не нужен в любом случае - просто удалите его.

В общем, я избегаю не абстрактного наследования с ORM.

Я не очень понимаю, что вы хотите достичь, но я хотел бы предложить 2 подхода (для лица, выпускников, профессор и т.д.), в зависимости от ваших потребностей:

1. Аннотация Наследование:

class Person: 
    class Meta: 
     abstract = True 

    # here you put all the common columns 

Тогда:

class Alumni(Person): 
    # the other columns - specific to alumn 

т.д.

Делая это, вы имеете одну таблицу на одну подтипом Person: Alumn, профессор и т.д.

2. Применение композиции:

class Alumn: 
    person = models.ForeignKey(Person, null=True, related_name="alumni_at") 
    university = ... 

class Professor: 
    person = models.ForeignKey(Person, null=True, related_name="professor_at") 
    university = ... 

Таким образом, вы можете сделать:

bob = Person.objects.create(first_name="bob", ...) 
Alumn.objects.create(person=bob, university="univ 1") 
Professor.objects.create(person=bob, university="univ 2") 
Alumn.objects.create(person=bob, university="univ 2")