我在tastypie中使用以下资源:
class ChoiceResource(LtgModelWithUuidResource):
"""
Resource for the choice model
"""
explanation = fields.ForeignKey(MultiLangTextFieldResource,attribute='explanation',full=True,null=True,
use_in=DisableOnPatch())
question = fields.ForeignKey('ltg_backend_app.base.api.question.QuestionResource',attribute='question',
use_in=DisableOnPatch())
keywords = fields.ManyToManyField(XrayResource,attribute='keywords',null=True,
use_in=DisableOnPatch())
class Meta(LtgResource.Meta):
queryset = Choice.objects.select_related('explanation','question').\
all().prefetch_related('keywords')
allowed_methods = ['get']
authentication = ApiKeyAuthentication()
authorization = Authorization()
order_by = ['id',]
问题:
查询
时API / V1 /选择/限= 100安培;偏移量= 200
结果中包含 id = 615
的选项。
查询
时api / v1 / choice /?limit = 100& offset = 2400
id = 615
的选择正在返回重新
total_count
是正确的(6010个对象)。可能的原因:
检查生成的SQL查询时,生成的SQL中没有ORDER BY
,但设置了OFFSET
和LIMIT
。
引用 Postgresql 文档:
使用
,否则排序未知LIMIT
时,最好使用ORDER BY
子句将结果行限制为唯一顺序。否则你会得到一个不可预知的查询行的子集---你可能会要求第十到第二十行,但第十到第二十行是什么排序?除非您指定ORDER BY
。查询优化器在生成查询计划时会考虑
LIMIT
,因此您很可能会得到不同的计划(产生不同的行顺序),具体取决于您为LIMIT
和{{1}提供的内容}}。因此,使用不同的OFFSET
/LIMIT
值来选择查询结果的不同子集将产生不一致的结果,除非您使用OFFSET
强制执行可预测的结果排序。这不是一个bug;这是SQL不承诺以任何特定顺序传递查询结果这一事实的固有后果,除非ORDER BY
用于约束订单。
我发现的解决方案:
我已将ORDER BY
添加到查询集中,现在看起来像这样:
order_by
问题:
我不确定我在这里遗漏了什么,或者我做错了什么。 任何澄清将不胜感激。
我认为,我不应该在django查询集或url查询参数中包含Choice.objects.select_related('explanation','question').\
all().prefetch_related('keywords').order_by('id)
以使其工作,或者至少它没有在tastypie docs。
感谢。
答案 0 :(得分:0)
ID通常以1开头。但情况并非总是如此。无论如何,默认排序将按其插入的顺序排列,因此这是预期的行为。
如果您想覆盖它,您可以像前面提到的那样在ordering
类中设置Media
参数。或者您也可以在GET查询中传递order_by
。
答案 1 :(得分:0)
在您的特定情况下,您需要在Queryset中使用.order_by
,因为字段id
并非Tastypie资源的一部分。只有Django模型。
参考:Tastypie source
在 general 中,最好的做法是将字段排序为尽可能靠近数据。如果该字段存在于Django模型中-请使用允许最佳SQL调用的queryset对其进行排序。但是,如果该字段是根据Tastypie资源计算的,则让Tastypie的order_by
处理它。