Django get() вызывает ЧЕТЫРЕ запроса [закрыто]
При глубокой отладке я обнаружил, что простой .get вызывает ЧЕТЫРЕ запроса:
kwargs['context']['user'] = models.Person.objects.get(
pk=16879
)
И postgresql.log выводит следующее:
2024-05-08 10:21:07.913 CEST [3987190] party@partytest LOG: statement: SELECT "structure_persondata"."id", "structure_persondata"."created_at", "structure_persondata"."updated_at", "structure_persondata"."person_id", "structure_persondata"."first_name", "structure_persondata"."middle_name", "structure_persondata"."last_name", "structure_persondata"."pesel", "structure_persondata"."validity_range" FROM "structure_persondata" WHERE ("structure_persondata"."person_id" = 16879 AND "structure_persondata"."validity_range" @> ('2024-05-08T08:21:05.002321+00:00'::timestamptz)::timestamp with time zone) ORDER BY "structure_persondata"."id" ASC LIMIT 1
2024-05-08 10:21:07.927 CEST [3987190] party@partytest LOG: statement: SELECT "structure_persondata"."id", "structure_persondata"."created_at", "structure_persondata"."updated_at", "structure_persondata"."person_id", "structure_persondata"."first_name", "structure_persondata"."middle_name", "structure_persondata"."last_name", "structure_persondata"."pesel", "structure_persondata"."validity_range" FROM "structure_persondata" WHERE ("structure_persondata"."person_id" = 16879 AND "structure_persondata"."validity_range" @> ('2024-05-08T08:21:05.002321+00:00'::timestamptz)::timestamp with time zone) ORDER BY "structure_persondata"."id" ASC LIMIT 1
2024-05-08 10:21:07.937 CEST [3987190] party@partytest LOG: statement: SELECT "structure_persondata"."id", "structure_persondata"."created_at", "structure_persondata"."updated_at", "structure_persondata"."person_id", "structure_persondata"."first_name", "structure_persondata"."middle_name", "structure_persondata"."last_name", "structure_persondata"."pesel", "structure_persondata"."validity_range" FROM "structure_persondata" WHERE ("structure_persondata"."person_id" = 16879 AND "structure_persondata"."validity_range" @> ('2024-05-08T08:21:05.002321+00:00'::timestamptz)::timestamp with time zone) ORDER BY "structure_persondata"."id" ASC LIMIT 1
2024-05-08 10:21:07.946 CEST [3987190] party@partytest LOG: statement: SELECT "structure_persondata"."id", "structure_persondata"."created_at", "structure_persondata"."updated_at", "structure_persondata"."person_id", "structure_persondata"."first_name", "structure_persondata"."middle_name", "structure_persondata"."last_name", "structure_persondata"."pesel", "structure_persondata"."validity_range" FROM "structure_persondata" WHERE ("structure_persondata"."person_id" = 16879 AND "structure_persondata"."validity_range" @> ('2024-05-08T08:21:05.002321+00:00'::timestamptz)::timestamp with time zone) ORDER BY "structure_persondata"."id" ASC LIMIT 1
Я думал, что этот код находится в каком-то цикле, но сделал вот что:
# raise ValueError('before')
kwargs['context']['user'] = models.Person.objects.get(
pk=16879
)
raise ValueError('after')
Сначала я запустил это с raise before, и никаких запросов вообще, затем я закомментировал это, и вижу 4 запроса....
Это не проблема журнала postgresql, я полагаю, потому что ранее декоратор login_required также запускал запросы, и каждый запрос один раз записывался в журнал.
обновить
Я обнаружил, что в моей модели есть методы:
def __str__(self) -> str:
return self.get_full_name()
def get_full_name(self, context_date: datetime = timezone.now()) -> str:
person_data = self.persondata_set.filter(validity_range__contains=context_date).first()
return ('†' if self.validity_range.upper else ''
+ f'{person_data.first_names} {person_data.last_name}' if person_data else '? ?')
и когда я комментирую get_full_name:
def __str__(self) -> str:
return 'test'
Количество запросов сократилось до двух:
2024-05-08 10:51:44.074 CEST [3993376] party@partytest LOG: statement: SELECT "structure_person"."id", "structure_person"."password", "structure_person"."last_login", "structure_person"."is_superuser", "structure_person"."username", "structure_person"."comment", "structure_person"."validity_range", "structure_person"."is_staff", "structure_person"."is_active", "structure_person"."date_joined" FROM "structure_person" WHERE "structure_person"."id" = 16879 LIMIT 21
2024-05-08 10:51:44.085 CEST [3993376] party@partytest LOG: statement: SELECT "structure_person"."id", "structure_person"."password", "structure_person"."last_login", "structure_person"."is_superuser", "structure_person"."username", "structure_person"."comment", "structure_person"."validity_range", "structure_person"."is_staff", "structure_person"."is_active", "structure_person"."date_joined" FROM "structure_person" WHERE "structure_person"."id" = 16879 LIMIT 21
И вопрос в том, ПОЧЕМУ существует четыре/два одинаковых запроса... И как рефакторить его до одного (или нескольких, но разных)
update 2 Я обнаружил, что даже внутренний запрос, сделанный auth, дублируется 4 раза...
Итак, источник проблем кроется в модели Person, которая наследует AbstractBaseUser и PermissionMixin
django-debug-toolbar показывает следующее:
/home/partytest/env/lib/python3.11/site-packages/whitenoise/middleware.py in __call__(124)
return self.get_response(request)
/home/partytest/env/lib/python3.11/site-packages/easyaudit/middleware/easyaudit.py in __call__(53)
response = response or self.get_response(request)
/home/partytest/env/lib/python3.11/site-packages/allauth/account/middleware.py in middleware(29)
response = get_response(request)
/home/partytest/env/lib/python3.11/site-packages/django/contrib/auth/decorators.py in _wrapper_view(22)
if test_func(request.user):
/home/partytest/env/lib/python3.11/site-packages/django/contrib/auth/decorators.py in <lambda>(51)
lambda u: u.is_authenticated,
/home/partytest/env/lib/python3.11/site-packages/django/contrib/auth/middleware.py in <lambda>(33)
request.user = SimpleLazyObject(lambda: get_user(request))
/home/partytest/env/lib/python3.11/site-packages/django/contrib/auth/middleware.py in get_user(13)
request._cached_user = auth.get_user(request)
/home/partytest/env/lib/python3.11/site-packages/django/contrib/auth/__init__.py in get_user(216)
user = backend.get_user(user_id)
/home/partytest/env/lib/python3.11/site-packages/django/contrib/auth/backends.py in get_user(157)
user = UserModel._default_manager.get(pk=user_id)
обновление 3
Я закомментировал все методы в классе Person.... и все равно auth выполняет 4 одинаковых запроса....