Django Rest Framework + django_filters для сериализованных значений - PullRequest
0 голосов
/ 11 апреля 2020

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

Вот мой model.py :

class Post(models.Model):
    post_id_number=models.AutoField(primary_key=True)
    variable_1 = models.CharField(max_length=50)
    variable_2 = models.CharField(max_length=50)
    variable_3 = models.CharField(max_length=50)

Вот мой Views.py :

class PostViewSet(viewsets.ModelViewSet):
    serializer_class = PostSerializers
    queryset = Post.objects.all()
    filterset_class = PostFilter

Вот мой serializers.py :

class PostSerializers(serializers.ModelSerializer):

    variable_not_in_the_model = serializers.SerializerMethodField()

    class Meta:
        model = Post
        fields = ('post_id_number',
            'variable_1', 
            'variable_2', 
            'variable_3', 
            'variable_not_in_the_model',
            )

    def get_variable_not_in_the_model(self, instance):
        return instance.variable_1 + ' ' + instance.variable_2 + ' ' + instance.variable_3

Вот мой фактический filters.py :

from .models import Post
import django_filters

class PostFilter(django_filters.FilterSet):
    class Meta:
        model = Post
        fields = {
            'variable_1': ['icontains'],
            'variable_2': ['icontains'],
            'variable_3': ['icontains']
        }

Вот то, что я хотел бы, чтобы мой filters.py был похож, но он не работает :

from .models import Post
import django_filters

class PostFilter(django_filters.FilterSet):
    class Meta:
        model = Post
        fields = {
            'variable_not_in_the_model': ['icontains']
        }

Есть ли способ фильтрации по сериализованным переменным, а не по переменным модели?

Большое спасибо за помощь!

Ответы [ 2 ]

0 голосов
/ 11 апреля 2020

Вот как я смог это сделать:

В моем views.py я создал новый View (не уверен, что он идеален, так как мне пришлось создать новый URL, но так как я использовал набор, который я не смог по-другому)

class PostAPIView(ListAPIView):
    serializer_class = PostSerializers

    def get_queryset(self, *args, **kwargs):
        #queryset_list = super(PostAPIView, self).get_queryset(*args, **kwargs)
        queryset_list = Post.objects.all()
        query = self.request.GET.get("q")
        if query:
            queryset_list = queryset_list.filter(
                Q(variable_1__icontains=query) |
                Q(variable_2__icontains=query) |
                Q(variable_3__icontains=query)
            ).distinct()
        return queryset_list

В моем urls.py я добавил:

path('api/filter/', PostAPIView.as_view(), name='test'),

И это работает ... Не уверен, что это оптимально, но работает.

Спасибо за вашу помощь !!!

0 голосов
/ 11 апреля 2020

Нельзя использовать значения из сериализатора в фильтре. Фильтр работает с полями модель / дБ. Но вы можете создать собственный набор запросов самостоятельно. Если вы просто хотите проверить, находится ли значение в одной из первых трех переменных, вы можете попробовать это:

import django_filters

from .models import Post


class PostFilter(django_filters.FilterSet):
    search = django_filters.CharFilter(method='filter_search')

    class Meta:
        model = Post

    def filter_search(self, qs, name, value):
        if value:
            return qs.filter((
                Q(variable_1__icontains=value) |
                Q(variable_2__icontains=value) |
                Q(variable_3__icontains=value)
            ))
        return qs

, а затем добавить параметр запроса ?search=something в вызове API

...