Django Tastypie关联资源时QuerySet过滤失效问题求助
解决Tastypie关联资源过滤规则不生效的问题
我之前也碰到过一模一样的问题,其实这是Tastypie处理关联字段的机制导致的:当你在RequestsResource里用ToManyField关联QuoteIndexResource时,它默认会直接调用Order模型的quotes关联管理器获取数据,并不会自动套用QuoteIndexResource里的过滤规则。下面给你几个可行的解决方案,你可以根据自己的场景选择:
方案一:在模型层面添加过滤后的关联属性
如果你的业务逻辑里经常需要获取未关闭的报价,推荐在Order模型里新增一个属性,预先过滤出符合条件的Quote对象:
class Order(models.Model): order_ref = models.CharField(null=True, blank=True) cost = models.DecimalField(null=True, blank=True) order_date = models.DateField(null=True, blank=True) delivery_date = models.DateField(null=True, blank=True) # ...其他原有字段 @property def active_quotes(self): # 只返回未关闭的报价 return self.quotes.filter(closed_date__isnull=True)
然后修改RequestsResource里的关联字段,指向这个新属性:
class RequestsResource(ModelResource): # 把关联的目标从原有的quotes改成active_quotes quotes = fields.ToManyField('api.resources.QuoteIndexResource', 'active_quotes', full=True, null=True) class Meta: queryset = Order.objects.all() resource_name = 'request'
方案二:在资源里重写脱水方法手动过滤
如果只需要在RequestsResource这个场景下应用过滤,可以重写dehydrate_quotes方法,在数据返回前手动过滤:
class RequestsResource(ModelResource): quotes = fields.ToManyField('api.resources.QuoteIndexResource', 'quotes', full=True, null=True) class Meta: queryset = Order.objects.all() resource_name = 'request' def dehydrate_quotes(self, bundle): # 过滤掉已关闭的报价 filtered_quotes = bundle.obj.quotes.filter(closed_date__isnull=True) # 调用字段的脱水方法处理过滤后的结果 return self.fields['quotes'].dehydrate(bundle, filtered_quotes)
方案三:全局强制应用过滤规则
如果所有使用QuoteIndexResource的场景都需要只返回未关闭的报价,可以修改QuoteIndexResource的get_queryset方法,强制添加过滤条件:
class QuoteIndexResource(ModelResource): class Meta: queryset = Quote.objects.all() resource_name = 'index_quote' def get_queryset(self, request=None): # 先获取父类的queryset,再添加过滤条件 queryset = super().get_queryset(request) return queryset.filter(closed_date__isnull=True)
这种方式的好处是不用修改任何关联字段的配置,只要引用了这个资源,就会自动应用过滤规则。
内容的提问来源于stack exchange,提问作者H30
相关产品推荐
相关产品推荐

