Различение детей родительской модели с наследованием Джанго - PullRequest
1 голос
/ 04 февраля 2010

В основном у меня есть Базовый класс, который называется «Программа». Затем у меня есть более конкретные типы моделей программ, которые используют Программу в качестве базового класса. Что касается 99% моих потребностей, мне все равно, является ли Программа одним из конкретных типов детей. Конечно, есть 1% времени, когда я хочу знать, является ли это один из детей.

Проблема в том, что если у меня есть, скажем, модель SwimProgram и модель CampProgram, использующая Program в качестве своей базы, то будет проблематично выяснить, что это такое, без множества блоков try / кроме. Я хочу что-то вроде следующего:

program = models.Program.objects.get(id=15)
if program.swimprogram:
    ## do stuff
elif program.campprogram:
    ## do stuff
else:
    ## do other stuff

Конечно, это вызывает исключение типа DidNotExist. Я мог бы использовать try / excepts, которые являются более уродливыми, или у меня могла бы быть программа, имеющая поле 'type', которое дети сохраняли при сохранении. И то и другое выполнимо, но мне любопытно, есть ли у кого-нибудь лучшие методы.

Ответы [ 3 ]

4 голосов
/ 04 февраля 2010

Вы пробовали hasattr ()? Примерно так:

if hasattr(program, 'swimprogram'):
    # ...
elif hasattr(program, 'campprogram'):
    # ...

Если вы не уверены в этом подходе, попробуйте сначала в простом тестовом приложении. Вот две простые модели, которые должны показать, будет ли он работать для вас, и версию django, которую вы используете (протестировано в django-1.1.1).

class Archive(models.Model):
    pub_date = models.DateField()

    def __unicode__(self):
        return "Archive: %s" % self.pub_date

class ArchiveB(Archive):
    def __unicode__(self):
        return "ArchiveB: %s" % self.pub_date

И затем вращение в раковине:

> a_id = Archive.objects.create(pub_date="2010-10-10").id
> b_id = ArchiveB.objects.create(pub_date="2011-11-11").id
> a = Archive.objects.get(id=a_id)
> b = Archive.objects.get(id=b_id)
> (a, b) # they both look like archive objects
(<Archive: Archive: 2010-10-10>, <Archive: Archive: 2011-11-11>)
> hasattr(a, 'archiveb')
False
> hasattr(b, 'archiveb') # but only one has access to an ArchiveB
True
1 голос
/ 05 февраля 2010

Пару недель назад кто-то из списка рассылки django-developers представил очень интересное расширение для ORM Django, которое заставляет QuerySets возвращать подклассные объекты вместо объектов родительского класса. Вы можете прочитать все об этом здесь:

http://bserve.webhop.org/wiki/django_polymorphic

Я сам еще не пробовал (но, безусловно, буду), но, похоже, подходит для вашего случая использования.

0 голосов
/ 04 февраля 2010

// Обновление

Как указано в комментариях к этому посту, я неправильно понял вопрос. Ответ ниже не решит проблему.


Привет, f4nt,

Самый простой способ, о котором я могу думать сейчас, был бы следующим:

program = models.Program.objects.get(id=15)

if program.__class__.__name__ == 'ModelA':
  # to something

if program.__class__.__name__ == 'ModelB':
  # to something

Чтобы сделать это немного лучше, вы можете написать метод в базовой модели:

class MyModel(models.Model):

  def instanceOfModel(self, model_name):
    return self.__class__.__name__ == model_name

Таким образом, код сверху будет выглядеть так:

program = models.Program.objects.get(id=15)

if program.instanceOfModel('ModelA'):
  # to something

if program.instanceOfModel('ModelB'):
  # to something

Но, как вы можете себе представить, это ужасно. Вы можете посмотреть на тип контента framework, который может помочь вам сделать то же самое, за исключением более элегантного.

Надеюсь, это поможет!

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