Django admin при автозаполнении поля переопределяет фильтр ModelForm

У меня проблема в админке django. Я хочу, чтобы одно из моих полей внешнего ключа было доступно для поиска, и я достиг этого, сделав его автозаполняемым.

class CollectionAdmin(VersionAdmin, admin.ModelAdmin):
    form = CollectionForm
    autocomplete_fields = ["task"]

Я также фильтрую этот внешний ключ в ModelForm.

class CollectionForm(forms.ModelForm):
    class Meta:
        model = Collection
        fields = "__all__"

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        if self.fields.get("task"):
            self.fields["task"].queryset = self.fields["task"].queryset.filter(
                status=TaskStatus.ASSIGNED
            )

Когда задача является не полем автозаполнения в Collection, мой фильтр работает как ожидалось. Однако, когда задачей является автозаполняемое поле в Коллекции, фильтр не работает. Вместо моего фильтра в форме вызывается метод task admin get_queryset, а это не то, что я хочу.

Метод TaskAdmin get_queryset просто фильтрует по пользователю, но я хочу больше фильтров, как вы видите выше, и для TaskStatus тоже.

def get_queryset(self, request):
    qs = super().get_queryset(request)
    if request.user.groups.filter(name=settings.COPYWRITER_GROUP).exists():
        return qs.filter(assigned_to=request.user)
    return qs

Повторяю, фильтр инициализации формы работает, если поле не является автозаполняемым.

Я попробовал удалить задачу из автозаполнения Коллекции и это сработало. Я хочу, чтобы фильтр моей формы не переопределялся, если поле является автозаполняемым.

Отвечаю на свой вопрос. Когда вы делаете поле автозаполняемым, оно напрямую вызывает метод get_queryset этой модели администратора. Так, в моем случае, TaskAdmin get_queryset вызывается каждый раз, когда я пытаюсь выбрать значение из выпадающего списка. Поэтому фильтр формы стал бесполезным, мы можем полностью удалить этот фильтр. Обходным решением является условная фильтрация объектов в TaskAdmin get_queryset. Я привожу пример,

    path = request.path
    if "autocomplete" in path:
        return super().get_queryset(request).filter()
    else:
        return super().get_queryset(request)

Это будет фильтровать набор запросов, если он вызывается из выпадающего списка. Спасибо!

Вернуться на верх