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)
Это будет фильтровать набор запросов, если он вызывается из выпадающего списка. Спасибо!