【问题标题】:How to do filtering in DateTime as null in Django rest framework?如何在 Django 休息框架中将 DateTime 过滤为空?
【发布时间】:2021-03-26 21:14:36
【问题描述】:

我只想用 Django rest 框架构建过滤 API。一个字段是 datetime2。我想过滤具有 NULL 值的记录作为 datetime2。

这是我的models.py

ruleend = models.DateTimeField(db_column='RuleEnd', blank=True, null=True)

这是我的 serializer.py

class ProductPriceSerializer(serializers.ModelSerializer): 
    class Meta: 
        model = ProductPrice 
        fields = ['pricingruleid', 'productkey', 'productcode', 'customerid', 'customerchain', 'productpriceusd', 'rulestart', 'ruleend', 'creatorupn', 'created', 'customername', 'productdescription'] 

这里是views.py

class ProductPriceViewSet(viewsets.ModelViewSet):    
    serializer_class = ProductPriceSerializer
    pagination_class = pagination.PageNumberPagination
    filter_backends = [DjangoFilterBackend, filters.OrderingFilter]
    filterset_fields = ['customerid', 'customername', 'productkey', 'productdescription', 'ruleend', 'rulestart']
    ordering_fields = ['customerid', 'productkey', 'rulestart']

    def get_queryset(self):
        self.pagination_class.page_size_query_param = 'page_size'
        return ProductPrice.objects.all()

urls.py

path('productprice/', ProductPriceViewSet.as_view({'get':'list','post':'create'}), name="product-price"), 

这让我很容易实现分页、过滤和排序。 但我有一个问题。我需要过滤 ruleend 中为空值的记录。

null 的有效日期/时间是什么?或者我应该在我的后端添加一些东西?

【问题讨论】:

  • 你能不能尝试不在请求中发送 ruleend 字段,看看会发生什么。
  • 如果我不发送 ruleend 字段,它会成功获取数据。但它不会过滤 ruleend 字段。

标签: python django rest pagination backend


【解决方案1】:

我找到了最佳答案。我可以使用客户过滤器。

from django_filters import rest_framework as restfilters

class ProductFilter(restfilters.FilterSet):
  isrulendNull=restfilters.BooleanFilter(field_name='ruleend', lookup_expr='isnull')
  class Meta:
    model = ProductPrice
    fields = ('customerid', 'customername', 'ruleend', 'productkey', 'productdescription', 'rulestart')

class ProductPriceViewSet(viewsets.ModelViewSet):    
    serializer_class = ProductPriceSerializer
    pagination_class = pagination.PageNumberPagination
    filter_backends = [DjangoFilterBackend, filters.OrderingFilter]
    filterset_class = ProductFilter

    # filterset_fields = ['customerid', 'customername', 'productkey', 'productdescription', 'ruleend', 'rulestart']
    ordering_fields = ['customerid', 'productkey', 'rulestart']

    def get_queryset(self):
        self.pagination_class.page_size_query_param = 'page_size'
        return ProductPrice.objects.all()

我将自定义字段设置为“isrulendNull”。

我希望这会帮助其他面临同样问题的人。

【讨论】:

    【解决方案2】:

    您需要在 ProductPriceSerializer 中添加此行 ruleend = fields.DateField(input_formats=['%Y-%m-%dT%H:%M:%S.%fZ']) 以通过您的日期时间输入进行验证:

    from rest_framework import serializers, fields
    
    class ProductPriceSerializer(serializers.ModelSerializer):
        ruleend = fields.DateField(input_formats=['%Y-%m-%dT%H:%M:%S.%fZ'])
        
        class Meta: 
            model = ProductPrice 
            fields = ['pricingruleid', 'productkey', 'productcode', 'customerid', 'customerchain', 'productpriceusd', 'rulestart', 'ruleend', 'creatorupn', 'created', 'customername', 'productdescription']
    

    更新: 用于过滤 ruleend 中具有空值的记录。您只需要像这样覆盖列表方法:

    class ProductPriceViewSet(viewsets.ModelViewSet):    
        serializer_class = ProductPriceSerializer
        pagination_class = pagination.PageNumberPagination
        filter_backends = [DjangoFilterBackend, filters.OrderingFilter]
        filterset_fields = ['customerid', 'customername', 'productkey', 'productdescription', 'ruleend', 'rulestart']
        ordering_fields = ['customerid', 'productkey', 'rulestart']
    
        def get_queryset(self):
            self.pagination_class.page_size_query_param = 'page_size'
            return ProductPrice.objects.all()
    
        def list(self, request, *args, **kwargs):
            queryset = self.filter_queryset(self.get_queryset())
    
            # Custom filter
            ruleend = str(request.GET.get('ruleend', ''))
            if ruleend.lower() == 'null':
                queryset = queryset.filter(ruleend__isnull=True)
    
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
    
            serializer = self.get_serializer(queryset, many=True)
            return Response(serializer.data)
    

    【讨论】:

    • 这将验证 ruleend 字段的输入格式。我想过滤空值。这将显示验证错误。并且使用序列化程序,我可以在不添加该行的情况下验证该字段。
    • 我知道了,刚刚更新了我的答案。希望这会有所帮助!
    • 谢谢,有道理。
    • 请帮助标记我的答案给其他人。谢谢!
    • 我正在寻找其他方法。我会尽快发布答案。
    猜你喜欢
    • 2021-11-06
    • 2013-04-08
    • 2021-10-10
    • 2021-11-26
    • 1970-01-01
    • 2015-02-25
    • 2016-04-25
    相关资源
    最近更新 更多