在带有 django-rest-framework 的过滤器中使用自定义方法
Posted
技术标签:
【中文标题】在带有 django-rest-framework 的过滤器中使用自定义方法【英文标题】:Using custom methods in filter with django-rest-framework 【发布时间】:2014-08-16 09:15:30 【问题描述】:我想在我的 REST API - see django docs on this 中过滤查询参数。 但是,我希望过滤的一个参数只能通过模型@property 获得
示例models.py:
class Listing(models.Model):
product = models.OneToOneField(Product, related_name='listing')
...
@property
def category(self):
return self.product.assets[0].category.name
这是根据django-filter docs 为我的Listing API 设置的
class ListingFilter(django_filters.FilterSet):
product = django_filters.CharFilter(name='product__name')
category = django_filters.CharFilter(name='category') #DOES NOT WORK!!
class Meta:
model = Listing
fields = ['product','category']
class ListingList(generics.ListCreateAPIView):
queryset = Listing.objects.all()
serializer_class = ListingSerializer
filter_class = ListingFilter
如何按listing.category 适当过滤?它不能直接在列表模型上使用。
【问题讨论】:
对于这种情况,另一个问题的答案可能会有所帮助:***.com/questions/14258338/… 【参考方案1】:使用 'action' 参数指定自定义方法 - see django-filter docs
首先定义一个使用类别参数值过滤查询集的方法:
def filter_category(queryset, value):
if not value:
return queryset
queryset = ...custom filtering on queryset using 'value'...
return queryset
列表过滤器应如下所示:
class ListingFilter(django_filters.FilterSet):
...
category = django_filters.CharFilter(action=filter_category)
...
【讨论】:
请注意,django-filteraction
已被 method
取代。 django-filter.readthedocs.io/en/latest/migration.html
Doc Reference MIgration 1.0 Changed action
to method
【参考方案2】:
为了数据库速度,您应该只将类别添加到您的列表模型中
class Listing(models.Model):
product = models.OneToOneField(Product, related_name='listing')
category = models.ForeignKey(Category)
然后使用post_save signal 保持字段更新
from django.dispatch import receiver
from django.db.models.signals import post_save
@receiver(post_save, sender=Product)
def updateCategory(sender, instance, created, update_fields, **kwargs):
product = instance
product.listing.category = product.assets[0].category.name
product.listing.save()
然后像过滤任何其他字段一样按其名称过滤:
class ListingFilter(django_filters.FilterSet):
...
category = django_filters.CharFilter(name='category__name')
...
【讨论】:
以上是关于在带有 django-rest-framework 的过滤器中使用自定义方法的主要内容,如果未能解决你的问题,请参考以下文章
如何在 django-rest-framework 中为 API 使用 TokenAuthentication
在视图集中创建的 Django-rest-framework 权限
django-rest-framework 是不是提供管理站点来管理模型?