我如何测试Django QuerySets是否按PK升序排序

t5zmwmid  于 2023-05-01  发布在  Go
关注(0)|答案(2)|浏览(74)
class Foo(models.Model):
    name = models.CharField(max_length=10)

    class Meta(object):
        ordering = ('pk', )

我想测试一下这个命令是否像我预期的那样工作。

def test_respect_ordering(self):
    Foo.objects.create(name="bar", pk=2)
    Foo.objects.create(name="baz", pk=1)
    results = Foo.objects.all()
    self.assertEqual("baz", results[0].name)
    self.assertEqual("bar", results[1].name)

尽管这正如我所期望的那样工作,但无论 meta类或其中定义的排序属性如何,我的测试都通过了。有没有什么方法可以测试这段代码的重要性?

  • 我为什么要测试这个?* 我的测试运行在SQLite中,但生产运行在mysql中。希望有一天,我们会使用一个更好的RDMBS,也许结果不会被PK返回所有这些RDMBS的。

Django文档表明排序不会自动发生。

hmmo2u0o

hmmo2u0o1#

如果在Meta类中省略ordering属性,则生成的SQL查询将没有ORDER BY子句(在1.这意味着你不能依赖行的顺序。
无序的SQL查询通常会有一个看起来有意义的顺序。这是因为查询计划很可能使用索引来减少查询时间,而索引在无序查询的行顺序中起着重要作用。Django模型生成的表只在主键上有一个索引,除非另有说明,所以一般来说,“无序”的顺序与按主键排序的顺序非常相似。
但这里绝对没有保证,这个订单也不能靠。查询计划在很大程度上取决于数据库引擎,对于同一引擎上非常相似的查询,它甚至可能会发生巨大的变化。
如果您需要特定的顺序,则应显式指定所需的顺序。这是保证特定订单的唯一可靠方法。

v8wbuo2f

v8wbuo2f2#

这是一个非常古老的问题。但是对于将来遇到这种情况的人来说,我建议的方法虽然很粗糙,但实际上确实测试了Django模型中查询集的顺序。

www.example.com

class Foo(models.Model):
    name = models.CharField(max_length=10)

    class Meta(object):
        ordering = ('name')

test_models。派

  • 这里的测试是用pytest编写的,但逻辑也可以与unittest模块一起使用。
import pyest
from myapp.models import Foo

@pytest.fixture
def foo_1():
    return Foo.objects.create(name="ZZZZ")

@pytest.fixture
def foo_2():
    return Foo.objects.create(name="AAAA")

@pytest.mark.django_db
def test_foo_ordering(foo_1, foo_2):
    foos = Foo.objects.all()
    # this checks that the name attribute second item in the queryset
    # should be greater than first item name attribute in the queryset.
    assert foos[0].name < foos[1].name

这个想法可以扩展到测试任何django模型中用于排序的其他属性。

相关问题