【发布时间】:2015-02-18 01:44:02
【问题描述】:
我能够通过过滤器成功查询一对多关系,但不是只获取一条包含匹配对象的记录,而是为每个匹配的过滤对象重复相同的记录。
例如,如果一家餐厅有许多符合我的过滤条件的检查,那么 Tastypie 会返回一个具有每个匹配分数的餐厅实例。
是否有任何方法可以取回单个记录,即使它有多个匹配的对象?
查询
http://test.com:8000/restaurants/api/restaurants/?format=json&onlinereports__insp_score__lte=35
models.py
class Restaurant(models.Model):
rest_permit = models.IntegerField(primary_key=True, verbose_name='Permit', db_index=True)
rest_name = models.CharField(max_length=200, verbose_name='Name', db_index=True)
class Meta:
ordering = ['rest_name']
select_on_save = True
class OnlineReport(models.Model):
insp_rest_permit = models.ForeignKey(Restaurant, null=False, to_field='rest_permit', related_name='onlinereports', db_index=True)
insp_score = models.DecimalField(verbose_name='Score', decimal_places=2, max_digits=5, db_index=True, null=True)
class Meta:
ordering = ['insp_date']
select_on_save = True
resources.py
class OnlineReportResource(ModelResource):
class Meta:
queryset = OnlineReport.objects.all()
resource_name = 'onlinereports'
filtering = {
'insp_score': ALL,
}
class RestaurantResource(ModelResource):
class Meta:
queryset = Restaurant.objects.all()
resource_name = 'restaurants'
filtering = {
'onlinereports': ALL_WITH_RELATIONS,
}
onlinereports = fields.ToManyField(
OnlineReportResource,
'onlinereports',
null=True,
full=True
)
返回示例:
{
limit: 20,
next: null,
offset: 0,
previous: null,
total_count: 2
},
objects: [
{
onlinereports: [
{
id: 2526,
insp_score: "11.00"
},
{
id: 47882,
insp_score: "-7.00"
},
{
id: 47880,
insp_score: "94.00"
}
],
rest_name: "Restaurant A",
rest_permit: 2037
},
{
onlinereports: [
{
id: 2526,
insp_score: "11.00"
},
{
id: 47882,
insp_score: "-7.00"
},
{
id: 47880,
insp_score: "94.00"
}
],
rest_name: "Restaurant A",
rest_permit: 2037
}
]
期望回报:
{
limit: 20,
next: null,
offset: 0,
previous: null,
total_count: 1
},
objects: [
{
onlinereports: [
{
id: 2526,
insp_score: "11.00"
},
{
id: 47882,
insp_score: "-7.00"
},
{
id: 47880,
insp_score: "94.00"
}
],
rest_name: "Restaurant A",
rest_permit: 2037
}
]
解决方案 将 .distinct() 添加到 RestaurantResource() 查询集有效:
class RestaurantResource(ModelResource):
class Meta:
queryset = Restaurant.objects.all().distinct()
resource_name = 'restaurants'
filtering = {
'onlinereports': ALL_WITH_RELATIONS,
}
【问题讨论】: