вопрос новичка по оптимизации запросов django db:
У меня есть пользовательская форма модели для редактирования объекта Destination, и я в конструкторе получаю набор запросов из связанной модели Visitor, которая имеет поле ManyToMany в Destination (см. РЕДАКТИРОВКУ о том, как использовать пользовательскую форму модели). )
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
EDIT
Объект 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
>>>
Спасибо