Django休息过滤自定义字段

时间:2017-06-12 02:12:50

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

我正在将unix日期转换为字符串日期并将其作为自定义只读字段传递。使用django-filter来过滤此自定义字段的最佳方法是什么?我得到的错误是无法解析关键字' convert_time'进入田野。选择是:..

模型类

```

class AccountT(models.Model):
    created_date_t = models.BigIntegerField(blank=True, null=True)
    def convert_time(self):
        result = time.strftime("%D", time.localtime(self.created_date_t))
        return result

```

Serializer Class

```

class AccountTSerializer(serializers.ModelSerializer):
    created_date = serializers.ReadOnlyField(source='convert_time')
    class Meta:
        model = AccountT
        fields = ('othermodelfield','othermodelfield', 'created_date', 
         )

```

ListAPiView

```

class AccountTListView(generics.ListAPIView):
    serializer_class = AccountTSerializer
    queryset = AccountT.objects.all()
    filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter,)
    filter_fields = ('othermodelfield','created_date_t')

```

3 个答案:

答案 0 :(得分:0)

class AccountT(models.Model):
    created_date_t = models.BigIntegerField(blank=True, null=True)
    created_date = models.DateField(null=True)

    def save(self, *args, **kwargs):
        self.created_date = self.convert_time()
        return super(IncomeExpense, self).save(*args, **kwargs)

    def convert_time(self):
        result = time.strftime("%D", time.localtime(self.created_date_t))
        return result


class AccountTListView(generics.ListAPIView):
    serializer_class = AccountTSerializer
    queryset = AccountT.objects.all()
    filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter,)
    filter_fields = ('othermodelfield','created_date')
class AccountTFilter(FilterSet):
    class Meta:
        model = AccountT
        fields = {
            'created_date': ['gte', 'lte'],
        }

class AccountTListView(generics.ListAPIView):
    serializer_class = AccountTSerializer
    queryset = AccountT.objects.all()
    filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter,)
    filter_class = AccountTFilter

答案 1 :(得分:0)

filter_fields选项是检查模型字段(不是序列化程序字段)以生成过滤器的快捷方式。由于created_date不是模型字段,因此您需要在filter_class上手动声明过滤器。声明的过滤器可以利用method参数,这样您就可以将传入日期转换为时间戳。有点像...

# filters.py
from django_filters import rest_framework as filters

class AccountTFilter(filters.FilterSet):
    # could alternatively use IsoDateTimeFilter instead of assuming local time.
    created_date = filters.DateTimeFilter(name='created_date_t', method='filter_timestamp')

    class Meta:
        model = models.AccountT
        # 'filter_fields' simply proxies the 'Meta.fields' option
        # no need to include declared fields
        fields = ['othermodelfield']

    def filter_timestamp(self, queryset, name, value):
        # transform datetime into timestamp
        value = ...

        return queryset.filter(**{name: value})

# views.py
class AccountTListView(generics.ListAPIView):
    filter_class = filters.AccountTFilter
    ...

答案 2 :(得分:0)

要实现这一点,我将在序列化程序(ConvertTimeField)上创建一个自定义字段:

import time

from .models import AccountT
from rest_framework import serializers


# Custom serializer field
# https://www.django-rest-framework.org/api-guide/fields/#custom-fields
class ConvertTimeField(serializers.ReadOnlyField):
    """
    Convert time Field.
    """

    def to_representation(self, value):
        return time.strftime("%D", time.localtime(value))

    def to_internal_value(self, data):
        """
        Here is where you could convert the incoming value
        (It's only needed if you want to perform modification before writing to the database)
        """


# Serializer
class AccountTSerializer(serializers.ModelSerializer):
    created_date = ConvertTimeField(source='created_date_t')

    class Meta:
        model = AccountT
        fields = ('othermodelfield', 'othermodelfield', 'created_date')

注意:您仍然需要以相同的格式(即UNIX时期)进行过滤时传递过滤器参数。如果需要更改,可以按照以下建议转换过滤器查询参数:https://www.django-rest-framework.org/api-guide/filtering/#filtering-against-query-parameters。 (尽管,还有其他方法可以尝试实现这一目标)