Привет, друзья! Я работаю над проектом на Django и у меня есть модель: ```python class AccountModel(models.Model): uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) user_name = models.CharField("Account name", null=True, blank=True, max_length=256) @property def task_inwork_count(self): return WorkModel.objects.filter(account=self.pk, status=1).count() class WorkModel(models.Model): account = models.ForeignKey("AccountModel", on_delete=models.CASCADE) status = models.ForeignKey("StatusOfWork", default=1, on_delete=models.CASCADE) ``` Также у меня есть форма, в которой поле выбора для "account" должно заполняться моделями AccountModel, у которых свойство `task_inwork_count` равно 0. Вот код формы: ```python class AddWorkForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(AddWorkForm, self).__init__(*args, **kwargs) choices = ( x for x in AccountModel.objects.filter( status=2, user_id=args[0]["user_id"] ) if x.task_inwork_count == 0 ) print(choices) self.fields["account"].queryset = choices class Meta: model = WorkModel fields = ["account"] ``` Однако, при инициализации формы возникает ошибка: ``` File ".venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner response = get_response(request) ^^^^^^^^^^^^^^^^^^^^^ File ".venv\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) ``` Не могли бы вы подсказать, в чем может быть проблема?
Ваша проблема заключается в том, что вы пытаетесь использовать свойство `task_inwork_count` в запросе при инициализации формы. При этом происходит выполнение отдельного SQL-запроса для каждой записи `AccountModel`, что может привести к ухудшению производительности и потенциальным ошибкам, особенно если в базе данных много записей. Кроме того, ваш код неэффективен с точки зрения запросов к базе данных. Вам нужно отфильтровать `AccountModel` на уровне базы данных, а не в Python-коде. Для этого вы можете использовать `Subquery` или `OuterRef` для фильтрации записей с `task_inwork_count == 0` на уровне базы данных. Вот как вы можете изменить ваш код: ```python from django.db.models import Count, OuterRef, Subquery from django import forms class AddWorkForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(AddWorkForm, self).__init__(*args, **kwargs) # Подзапрос, который считает задачи со статусом=1 subquery = WorkModel.objects.filter( account=OuterRef('pk'), status=1 ).values('account').annotate(count=Count('id')).values('count') # Фильтр для выбора только тех AccountModel, у которых count = 0 self.fields["account"].queryset = AccountModel.objects.filter( status=2, user_id=args[0]["user_id"] ).annotate(task_inwork_count=Subquery(subquery)).filter(task_inwork_count=0) class Meta: model = WorkModel fields = ["account"] ``` В этом примере: 1. Мы создаём подзапрос, который использует `OuterRef`, чтобы сослаться на `AccountModel`, и подсчитывает количество связанных `WorkModel` с `status=1`. 2. Далее мы аннотируем `AccountModel`, добавляя поле `task_inwork_count`, основанное на результате подзапроса. 3. Наконец, мы фильтруем аннотированный queryset, чтобы оставить только те записи, где `task_inwork_count` равно 0. Этот подход более производителен, так как условия фильтрации выполняются непосредственно на уровне СУБД, что позволяет избежать множественных запросов из Python к базе данных.
Мне надо ему дать AccountModel.objects.filter(status=2, user_id=args[0]["user_id"]), но что бы она еще фильтровалась по @property task_inwork_counttask_inwork_count нужно переносить на уровень SQL, читай про annotate и aggregate