我有这个型号:
class Auction(models.Model):
start_price = models.IntegerField()
price_step = models.IntegerField()
finish_time = models.DateTimeField()
@property
def is_active(self):
return self.finish_time > timezone.now()
我的序列化程序类中也有这个:
class AuctionSerializer(serializers.ModelSerializer):
is_active = serializers.ReadOnlyField()
class Meta:
model = Auction
fields = '__all__'
这在我的观点课程中:
class AuctionViewSet(ModelViewSet):
queryset = Auction.objects.all()
serializer_class = AuctionSerializer
filter_backends = (DjangoFilterBackend,)
filter_fields = ('is_active',)
但是它会引发Meta.fields'包含未在此FilterSet上定义的字段:is_active"。我可以将它用作序列化器字段,但我无法通过此字段进行过滤。如何通过模型属性正确实现过滤,而不仅仅是模型字段?
答案 0 :(得分:1)
AFAIK,django-filter不支持按属性过滤。
这样做的一种方法是按原样公开模型;并期望FE相应地过滤。
例如:过滤器URI可能看起来像http://localhost:8000/api/auctions/?finish_time__gte=2018-04-28T00:00:00
但是,如果你想要一个明确的声明;您可以覆盖get_queryset
中的ModelViewSet
方法,如下所示:
class AuctionViewSet(ModelViewSet):
queryset = Auction.objects.all()
serializer_class = AuctionSerializer
filter_backends = (DjangoFilterBackend,)
filter_fields = ('is_active',)
def filter_active(qs):
return qs.filter(finish_time__gte=timezone.now())
def filter_inactive(qs):
return qs.filter(finish_time__lt=timezone.now())
def get_queryset():
qs = super(AuctionViewSet, self).get_queryset()
is_active = self.request.GET.get('is_active', None) # This will be a string
if is_active is None:
pass
elif is_active == 'true':
qs = self.filter_active(qs)
elif is_active == 'false':
qs = self.filter_inactive(qs)
else:
pass # Some other value
return qs