вопрос новичка по оптимизации запросов django db:
У меня есть настраиваемая форма модели для редактирования объекта Destination, и я в конструкторе получаю набор запросов из связанной модели Visitor, которая имеет поле ManyToMany в Destination (см. EDIT, чтобы узнать причину использования настраиваемой формы модели)
print "loading initial choices"
visitor_choices, visitor_initial = [], []
visitor_set = self.instance.visitor_set.all()
print visitor_set
for obj in Visitor.objects.all():
visitor_choices.append((obj.pk, obj.name))
#if visitor_set.filter(pk=obj.pk # this hits the db every time!
if obj in visitor_set:
visitor_initial.append(obj.pk)
self.fields['visitors'].choices = visitor_choices
self.fields['visitors'].initial = visitor_initial
print "finished loading initial choices"
Идея заключалась в том, чтобы загрузить связанный visitor_set в переменную, чтобы избежать повторных запросов, чтобы проверить, присутствует ли каждый посетитель в visitor_set. Это лучший подход?
Кроме того, если я включу ведение журнала базы данных (как описано в этом вопросе , второй ответ), я вижу повторяющийся запрос (3-й оператор SELECT) для выбора всех посетителей для целевого идентификатора 1, но этого нет в написанном мной коде, откуда он взялся?
loading initial choices
(0.000) SELECT "testapp_visitor"."id", "testapp_visitor"."name" FROM "testapp_visitor" INNER JOIN "testapp_visitor_destinations" ON ("testapp_visitor"."id" = "testapp_visitor_destinations"."visitor_id") WHERE "testapp_visitor_destinations"."destination_id" = 1 LIMIT 21; args=(1,
)
[<Visitor: MIMA>, <Visitor: MIMO>, <Visitor: MIMU>]
(0.000) SELECT "testapp_visitor"."id", "testapp_visitor"."name" FROM "testapp_visitor"; args=()
(0.000) SELECT "testapp_visitor"."id", "testapp_visitor"."name" FROM "testapp_visitor" INNER JOIN "testapp_visitor_destinations" ON ("testapp_visitor"."id" = "testapp_visitor_destinations"."visitor_id") WHERE "testapp_visitor_destinations"."destination_id" = 1 ; args=(1,)
finished loading initial choices
ИЗМЕНИТЬ
Объект Destination
, о котором я говорю, является связанной стороной поля ManyToMany
объекта Visitor
. Если бы моя форма редактировала сам объект Visitor, то Django автоматически обрабатывал бы поле ManyToMany
. Но чтобы сделать это в модельной форме для Destination
, мне нужно добавить поле множественного выбора для Visitor
и настроить метод __init__
для загрузки вариантов выбора и начального выбора для него.
Однако вопрос заключается в том, как обрабатывать набор запросов и таинственный второй sql для загрузки многих значений, которые я также могу видеть из оболочки:
>>> from testapp.forms import DestinationForm
>>> from testapp.models import Destination, Visitor
>>> dest = Destination.objects.get(pk=1)
(0.001) SELECT "testapp_destination"."id", "testapp_destination"."destination" FROM "testapp_destination" WHERE "testapp_destination"."id" =
1 ; args=(1,)
>>> destinationForm = DestinationForm(instance=dest)
loading initial choices
(0.000) SELECT "testapp_visitor"."id", "testapp_visitor"."name" FROM "testapp_visitor" INNER JOIN "testapp_visitor_destinations" ON ("testap
p_visitor"."id" = "testapp_visitor_destinations"."visitor_id") WHERE "testapp_visitor_destinations"."destination_id" = 1 LIMIT 21; args=(1,
)
[<Visitor: MIMA>, <Visitor: MIMO>, <Visitor: MIMU>]
(0.000) SELECT "testapp_visitor"."id", "testapp_visitor"."name" FROM "testapp_visitor"; args=()
(0.000) SELECT "testapp_visitor"."id", "testapp_visitor"."name" FROM "testapp_visitor" INNER JOIN "testapp_visitor_destinations" ON ("testap
p_visitor"."id" = "testapp_visitor_destinations"."visitor_id") WHERE "testapp_visitor_destinations"."destination_id" = 1 ; args=(1,)
finished loading initial choices
>>>
Спасибо
ModelForm
для модели, в которойvisitor
являетсяManyToManyField
? - person Bernhard Vallant   schedule 30.11.2011