【问题标题】:MultipleObjectsReturned: get() returned more than one Feed -- it returned 2MultipleObjectsReturned:get() 返回了多个 Fe​​ed - 它返回了 2
【发布时间】:2017-10-24 08:24:44
【问题描述】:

我正在为django-model 编写一些简单的测试,而我只是使用assertEqualassertNotEqual。 现在我还没有完全掌握在这种情况下如何测试BooleanField。我有一个像这样的model 字段:

duplicate = models.BooleanField(default=False)

我正在为它写这个测试,只是为了检查它是否相等:

def test_feed_duplicate_create(self):
    stefan_feed_duplicate = Feed.objects.get(duplicate='False')
    milan_feed_duplicate = Feed.objects.get(duplicate='False')
    self.assertEqual(
        stefan_feed_duplicate.duplicate, 'False'
    )
    self.assertEqual(
        milan_feed_duplicate.duplicate, 'False'
    )

但我面临的错误是:

(venv) vagrant@jessie:/var/www/vhosts/bspotted.net/app$ ./manage.py test --keepdb socialmedia
nosetests socialmedia --verbosity=1
Using existing test database for alias 'default'...
............E....................
======================================================================
ERROR: test_feed_duplicate_create (app.socialmedia.tests.test_feed_model.CommentsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/var/www/vhosts/bspotted.net/app/socialmedia/tests/test_feed_model.py", line 225, in test_feed_duplicate_create
    stefan_feed_duplicate = Feed.objects.get(duplicate='False')
  File "/var/www/vhosts/bspotted.net/venv/lib/python3.4/site-packages/django/db/models/manager.py", line 127, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/var/www/vhosts/bspotted.net/venv/lib/python3.4/site-packages/django/db/models/query.py", line 338, in get
    (self.model._meta.object_name, num)
socialmedia.models.feed.MultipleObjectsReturned: get() returned more than one Feed -- it returned 2!

----------------------------------------------------------------------
Ran 33 tests in 0.159s

有人能解释一下在这种情况下测试BooleanField 的正确方法是什么吗?谢谢。

【问题讨论】:

  • 删除布尔值周围的括号,不要使用get,如果从数据库返回多个对象,get 将抛出异常。改用过滤器,它将返回查询集对象Feed.objects.filter(duplicate=False),但如果您只想要该对象,那么您可以从查询集结果Feed.objects.filter(duplicate=False).first() 中获取第一个对象,然后在您的断言语句中只使用用户self.assertFalse(stefan_feed_duplicate.duplicate)
  • 好的,这很好,我知道了,现在,谢谢你向我解释这个
  • 除了id之外,你的模式中还有什么唯一的字段吗?如果是,使用它们,如果没有,使用id,检索单个对象。
  • 其实我很感谢你的提示。

标签: django testing


【解决方案1】:

QuerySetget 方法只返回 1(一个)条目。如果它无法检索一个条目,它将抛出错误,如果它检索多个条目,它将抛出一个错误。

如果您希望有多个条目,或者最终根本没有条目,您应该使用filter 方法,它会返回一个QuerySet

在您的特定情况下,您不能仅根据字段duplicate 检索一个条目。它是一个BooleanField,并且会有值为True 的条目和值为False 的条目。

您必须根据另一个字段检索 stefanmilan 的特定条目。

【讨论】:

    【解决方案2】:

    当通过get() 中指定的选择选择多个对象时,通常会出现这种情况。在您的情况下,多个对象满足duplicate == False 标准。

    get() 仅应在您确定只返回一个结果时使用,例如通过使用id 作为选择器。

    在您的情况下,当您期望多个结果时,您可以使用 filter() 而不是 get()。但是,filter() 不返回对象,而是返回 QuerySet。因此,您必须调整断言以比较 QuerySet 的条目。

    【讨论】:

    • 很好的答案,但最后一句话有一个陷阱。如果他使用filter(),他将得到QuerySet,这在self.assertEqual 中没有意义。
    猜你喜欢
    • 2021-06-24
    • 2020-08-14
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 2022-01-11
    相关资源
    最近更新 更多