Por lo tanto, estoy creando un filtro personalizado para mi modelo y quiero que todos los campos en ese filtro no usen 'exacto' sino 'contiene', pero no quiero agregar manualmente todos los campos. Estoy tratando de hacer algo como esto:

from django_filters import FilterSet
from polls.models import Question, Choice
from django_filters import rest_framework

class ChoiceFilter(FilterSet):
    for field in Choice._meta.get_fields():

        field = rest_framework.CharFilter(lookup_expr='icontains')
    #question = rest_framework.CharFilter(lookup_expr='icontains') #this works want to generalize this

    class Meta:
        model = Choice
        fields = '__all__'

Entonces la segunda línea funciona, pero mi bucle for no funciona y mi filtro usa 'exacto' en lugar de 'contiene'

1
somedude1234 28 jun. 2019 a las 16:49

2 respuestas

La mejor respuesta

Puede crear una clase personalizada FilterSet que anule el método get_fields para cambiar las búsquedas de exact a icontains:

class CustomFilterSet(FilterSet):
    @classmethod
    def get_fields(cls):
        fields = super().get_fields()
        for name, lookups in fields.items():
            lookups[:] = ['icontains']
        return fields

Ahora simplemente hace ChoiceFilter heredar de esta clase:

class ChoiceFilter(CustomFilterSet):
    class Meta:
        model = Choice
        fields = '__all__'

Tenga en cuenta que se considera peligroso usar __all__ para los campos.

1
ikkuh 28 jun. 2019 a las 14:23

A partir de Django-Filter v2.3, podría definir FILTERS_DEFAULT_LOOKUP_EXPR = 'icontains' en su settings.py, que cambiará el comportamiento predeterminado.

0
Miracl3 15 sep. 2020 a las 08:37