Как получить подклассный объект модели Django - PullRequest
2 голосов
/ 14 мая 2009

Когда у меня есть заданный класс модели Django, подобный этому:

class BaseClass(models.Model):
     some_field = models.CharField(max_length = 80)
     ...

и некоторые его подклассы, например

class SomeClass(BaseClass):
     other_field =  models.CharField(max_length = 80)

Тогда я знаю, что могу получить производный объект, вызвав

base  = BaseClass.objects.get(pk=3)
my_obj= base.someclass

Теперь возникает проблема, что у меня есть несколько подклассов, и все, что у меня есть, это экземпляр базового класса. Как я могу добраться до подкласса, не зная заранее его класс?


Идея состоит в том, чтобы загрузить соответствующее представление и позволить этому все делать. Функции моего проекта имеют только ограниченный набор действий по умолчанию для этих моделей, таких как просмотр, редактирование, удаление и т. Д. Я не хочу показывать тип данного объекта через URL, поэтому «нормальный способ» недоступен

Ответы [ 4 ]

3 голосов
/ 14 мая 2009

Нет встроенного способа.

Возможно, лучше всего определить поле derived_type в базовом классе, которое устанавливается автоматически при сохранении производного класса. Тогда у вас может быть метод get_derived на базе, который проверяет значение derived_type и возвращает фактический производный объект.

2 голосов
/ 22 марта 2012

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

посмотрите на пример мест и ресторанов. Базовый объект - это место, а подкласс - ресторан. Вы можете получить подкласс по place.restaurant, что дает исключение, которое вы можете поймать, если место не является рестораном. Я добавляю это, потому что принятый ответ может быть немного устаревшим и привел меня к неправильному пути.

2 голосов
/ 14 мая 2009

Как я могу добраться до подкласса, не зная заранее его класс?

Почему это было бы полезно? Если вы не знаете, какой класс вам нужен, вы также не будете знать, какие методы вызывать или какие атрибуты можно проверить.


Идея состоит в том, чтобы загрузить соответствующее представление и позволить этому все делать. Функции моего проекта имеют только ограниченный набор действий по умолчанию для этих моделей, таких как просмотр, редактирование, удаление и т. Д. Я не хочу показывать тип данного объекта через URL, поэтому «нормальный способ» недоступен

Если вы заранее знаете набор подклассов моделей или хотите зарегистрировать их в централизованном списке, вы можете сделать что-то вроде этого:

VIEWS = [('subclass_a', a_views), ('subclass_b', b_views)]

def edit(request):
    base = (get base somehow)

    for attrname, views in VIEWS:
        if getattr(base, attrname) is not None:
            return views['edit']

В зависимости от того, сколько разных видов у вас есть, вы можете абстрагировать поиск в отдельную функцию, поэтому конечный вид выглядит примерно так:

def edit(request):
    return generic_base_view(request, 'edit')
0 голосов
/ 03 апреля 2014

Если вы используете InheritanceManager из django-model-utils, вы можете выбирать подклассы при запросе, не зная, что они опередили время.

https://django -model-utils.readthedocs.org / ен / последний / managers.html # inheritancemanager

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