5👍
The filterset_fields
option is a shortcut that inspects model fields (not serializer fields) in order to generate filters. Since created_date
isn’t a model field, you’ll need to manually declare a filter on a filterset_class
. Declared filters can take advantage of the method
argument, which will allow you to transform the incoming date into your timestamp. Something like…
# 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
# 'filterset_fields' simply proxies the 'Meta.fields' option
# Also, it isn't necessary to include declared fields here
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):
filterset_class = filters.AccountTFilter
...
Note: The old filter_*
options have since been renamed to filtserset_*
.
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
- [Django]-Overriding methods for defining custom model field in django
- [Django]-Django models.DateField prevent past
0👍
To achieve this I would create a custom field on the serializer (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')
NOTE: You still need to pass your filter argument in the same format i.e UNIX epoch when you filter. If you need to change that you can convert your filter query param as suggested here: https://www.django-rest-framework.org/api-guide/filtering/#filtering-against-query-parameters. (Although, there are also other ways you could try accomplish that)