我正在将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')
```
答案 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。 (尽管,还有其他方法可以尝试实现这一目标)