2017-01-22 3 views
0

У меня есть BaseModel (models.Model) и ExtendedModelA (BaseModel) и ExtendedModelB (BaseModel). ExtendedModelA и ExtendedModelB имеют внешние поля для других моделей. Их методы unicode возвращают поле этой модели, связанной с внешним ключом.Django - расширенные расширенные модели запросов

У меня есть выпадающее меню, которое я хочу заполнить объектами BaseModel (что, естественно, включает объекты ExtendedModelA и ExtendedModelB). Для этого мне нужен набор запросов, который получит все расширенные объекты (тип A и B) и связанные с ними объекты.

У меня есть объединенное QuerySet:

queryset = BaseModel.objects.filter(type=1).select_related('extendedmodela') | BaseModel.objects.filter(type=2).select_related('extendedmodelb') 

Проблема заключается в том, что юникода представление BaseModel представлен в выпадающем списке. Если добавить метод Юникода к классу BaseModel, который имеет условие:

if hasattr(self, extendedmodela): 
     return self.extendedmodela.__unicode__() 
    else: 
     return self.extendedmodelb.__unicode__() 

В результате запросов к базе данных для каждого объекта.

Любые идеи о том, как избавиться от этого беспорядка?

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

Приветствия,

Дин

+0

Не можете ли вы иметь смешанный список/набор экземпляров 'ExtendedModelA/B'? – schwobaseggl

+0

Я не уверен - довольно новый для Django –

ответ

1

Вы используете select_related, что хорошо. Я думаю, вы можете оптимизировать свой запрос, используя Q, который по существу позволяет фильтровать для либо типа 1, либо типа 2 в этом случае.

from django.db.models import Q 

BaseModel.objects.filter(Q(type=1) | Q(type=2)).select_related('extendedmodela').select_related('extendedmodelb') 

EDIT

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

.select_related('extendedmodela', 'extendedmodela__fkfieldname') 
+0

Это не поможет тому, что методы Unicode A и B будут обращаться к внешним ключам, которые нужно будет искать один за другим. Вы можете добавить необходимые отношения к существующему 'select_related'. – schwobaseggl

+0

Итак, чтобы решить проблему вызова внешнего ключа в Юникоде, я просто добавляю больше «select_related», чтобы этот запрос мог передавать имена, в которых есть ссылки на внешние ключи. –

+0

@DeanSherwin Вы можете использовать обозначение с двойным подчеркиванием для достижения более глубоких полей, относящихся к родственным моделям. – denvaar

0

Почему не просто передать смешанный мешок выпадающего меню. Это больше не является QuerySet, но выпадающий не будет возражать:

qs = list(ExtendedModelA.objects.select_related('whatever_fk_needed')) +\ 
    list(ExtendedModelB.objects.select_related('whatever_fk_needed')) 

Независимо экземпляр выбран, будет иметь тот же id как его BaseModel например.

+0

Я не буду этого делать, потому что изменение списка приведет к тому, что запрос будет оцениваться. Вместо этого вы можете использовать 'values_list'. – denvaar

+0

Запрос будет оцениваться в любом случае, как только выпадающее меню будет отображаться. – schwobaseggl

+0

Я думаю, это правда. – denvaar

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