我无法让Tastypie在ManyToMany查询中正常运行。
以下是我的模型的简化版本。
class Buttons(models.Model):
name = models.CharField(max_length=255)
deleted = models.IntegerField()
date_entered = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
jacket = models.ManyToManyField('Jackets', through='JacketsButtons', related_name='buttons_jackets', blank=True)
class Meta:
app_label = 'habby'
db_table = u'buttons'
#joining table
class JacketsButtons(models.Model):
date_modified = models.DateTimeField(auto_now=True)
deleted = models.IntegerField()
jacket_id = models.ForeignKey('Jackets')
button_id = models.ForeignKey('Buttons')
class Meta:
app_label = 'habby'
db_table = u'jacket_buttons'
class Jackets(models.Model):
name = models.CharField(max_length=450, blank=True)
deleted = models.IntegerField()
date_entered = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
class Meta:
app_label = 'habby'
db_table = u'jackets'
这些是资源模型:
class ButtonsResource(ModelResource):
jacket = fields.ToManyField('habby.JacketsResource', "jacket", null=True, readonly=True)
class Meta:
queryset = Buttons.objects.filter(jacketsbuttons__deleted=0)
resource_name = 'buttons'
always_return_data = True
filtering = {
"id": ALL,
"name": ALL,
"deleted" : ALL,
"date_entered" : ALL,
"date_modified" : ALL,
"jacket" : ALL_WITH_RELATIONS
}
class JacketsResource(ModelResource):
class Meta:
queryset = Jackets.objects.filter(deleted=0)
resource_name = 'jackets'
always_return_data = True
filtering = {
"id": ALL,
"name": ALL,
"deleted" : ALL,
"date_entered" : ALL,
"date_modified" : ALL,
}
现在,我要做的是过滤按钮,通过连接表上的一个参数和夹克表上的一个参数,它在django中完美运行:
Buttons.objects.filter(
jacket__id="1",
jacketsbuttons__deleted=0)
但我无法弄清楚如何在TastyPie中做同等效。
我试过这个:
GET /api/v1/buttons/?jacket__id=1&jacketsbuttons__deleted=0
但TastyPie忽略了jacketsbuttons__deleted参数,因为它在Resource.build_filters()中被删除,因为它在self.fields中找不到。
然后我尝试了上面显示的设置,在那里我将条件指定为元类中查询集的一部分,这让我想到了这个问题的主题。
查询资源并指定jacket__id时,它会完全忽略查询集,因此会忽略连接表过滤器。
...
class Meta:
queryset = Buttons.objects.filter(jacketsbuttons__deleted=0)
...
GET /api/v1/buttons/?jacket__id=1
但是当我将jacket__id参数替换为另一个原生按钮参数,或者甚至省去所有参数时它都能正常工作,正确使用了连接表过滤器。
GET /api/v1/buttons/?name=round_button
我还尝试了TastyPie Cookbook中建议的“按请求更改查询集”,但是当我尝试通过jacket__id进行查询时,它也被忽略了:
class Meta:
queryset = Buttons.objects.all()
def get_object_list(self, request):
return super(ButtonsResource, self).get_object_list(request).filter(jacketsbuttons__deleted=0)
那么,为什么会被忽略? 我怎么强迫它被使用?
此外,是否有其他人知道如何更好地实现这一目标?
提前致谢。
Jayd
答案 0 :(得分:1)
之前我有过类似的情况,然后我做的是修改apply_filter函数到这样的事情:
def apply_filters(self, request, applicable_filters):
"""
accept extra query in request
"""
query_foo = request.GET.get('foo', None)
query_bar = request.GET.get('bar', None)
semi_filtered = super(RouteResource, self).apply_filters(request, applicable_filters)
if query_foo:
filtered_objects = semi_filtered.filter(..something with query_foo..)
return filtered_objects
else:
return semi_filtered
您可以随时查看tastypie的资源代码,了解此功能的工作原理。希望它有所帮助。