Создание универсального дизайна наследования таблиц в Django - PullRequest
4 голосов
/ 11 ноября 2009

Прежде всего, некоторые ссылки на страницы, которые я использовал для справки: SO вопрос и документы Django по родовые отношения и наследование нескольких таблиц .

Пока у меня настроен дизайн наследования нескольких таблиц. Объекты (например, Автомобиль, Собака, Компьютер) могут наследовать класс Item. Мне нужно иметь возможность получать элементы из БД, получать подкласс и делать с ним что-то. Мой дизайн не позволяет извлекать различные типы объектов один за другим, поэтому мне нужно использовать контейнер Item, чтобы объединить их все в один. Когда у меня есть Предмет, документы Django говорят, что я могу получить подкласс, связав атрибут с именем модели (например, myitem.car или myitem.computer).

Я не знаю, на какой тип объекта ссылается мой предмет, так как я могу получить ребенка? Есть ли встроенный способ сделать это? Вот некоторые другие идеи, которые у меня были: (некоторые безумнее других)

  1. Я думал, что мог бы добавить что-то вроде GenericForeignKey для элемента, который ссылается на ребенка, но я в этом сомневаюсь даже законно для родительского класса относиться через ForeignKey к ребенку класс.
  2. Полагаю, у меня мог быть ForeignKey (ContentType) в элементе класс, и найти атрибут Элемент, чтобы получить ребенка на основе Имя ContentType.
  3. Наконец, хотя это уродливый метод, я мог бы сохранить список типов объектов и пробовать каждый из них в качестве атрибута до тех пор, пока не будет выдана ошибка DoesNotExist.

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

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

Ответы [ 2 ]

4 голосов
/ 11 ноября 2009

Я сделал нечто похожее на метод 2 в одном из моих проектов:

from django.db import models
from django.contrib.contenttypes.models import ContentType

class BaseModel(models.Model):
    type = models.ForeignKey(ContentType,editable=False)
    # other base fields here

    def save(self,force_insert=False,force_update=False):
        if self.type_id is None:
            self.type = ContentType.objects.get_for_model(self.__class__)
        super(BaseModel,self).save(force_insert,force_update)

    def get_instance(self):
        return self.type.get_object_for_this_type(id=self.id)
1 голос
/ 11 ноября 2009

Было бы лучше составить модели модели Item и ItemType. Модели подклассов звучат хорошо и полезны в некоторых крайних случаях, но в целом безопаснее и эффективнее придерживаться тактики, которая работает с вашей базой данных, а не против нее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...