【问题标题】:Django Rest Framework + django_filters on serialized valuesDjango Rest Framework + django_filters 对序列化值
【发布时间】:2020-07-23 20:34:11
【问题描述】:

我正在尝试过滤不在我的模型上的序列化值,但我无法理解这一点。

这是我的 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']
        }

有没有办法可以过滤序列化变量而不是模型变量?

非常感谢您的帮助!

【问题讨论】:

  • 过滤过程发生在数据库级别,针对现有的数据库字段(或注释字段)。因此,您不能针对 非模型字段 进行过滤
  • 谢谢,我不知道!

标签: django django-rest-framework django-filter


【解决方案1】:

这是我能做到的:

在我的 views.py 中,我创建了一个新视图(不确定它是否理想,因为我必须创建一个新的 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'),

它正在工作......不确定它是否是最佳的,但工作正常。

感谢您的帮助!!!

【讨论】:

    【解决方案2】:

    您不能在过滤器中使用来自序列化程序的值。过滤器适用于模型/数据库字段。但是您可以自己构建自定义查询集。如果您只想检查该值是否在前三个变量之一中,您可以试试这个:

    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
    

    然后在您的 API 调用中添加 ?search=something 查询参数

    【讨论】:

    • 非常感谢。我在尝试以这种方式添加它作为过滤器时遇到了问题,但成功但从我的实际视图集中创建了一个 ListAPIView dinstinct 并几乎完全使用了你解释的内容。谢谢!!
    猜你喜欢
    • 2021-10-02
    • 2018-10-29
    • 1970-01-01
    • 2017-07-12
    • 2016-10-22
    • 2015-06-29
    • 2015-01-12
    • 2016-07-21
    • 2015-12-13
    相关资源
    最近更新 更多