【问题标题】:How to compare Django Querysets如何比较 Django 查询集
【发布时间】:2019-06-04 14:15:37
【问题描述】:

我整个上午都在苦苦挣扎,试图弄清楚如何比较两个不同的查询集。我的模型中有两个manytomanyfields,我试图弄清楚它们是否相同。

我通过查看此特定问题进行研究:How do I test Django QuerySets are equal?

我正在使用基于类的视图...并且我有一个包含两个多字段的模型...

我的模型...

class Author(models.Model):

title = models.ManyToManyField(User,blank=True,related_name='title')
title1 = models.ManyToManyField(User,blank=True,related_name='title1)

我的观点...

class AuthorDetailView(DetailView):
    model = Author 

def get_context_data(self, **kwargs):
    context = super(AuthorDetailView, self).get_context_data(**kwargs)
    title = list(Author.objects.filter(title))
    title1 = list(Author.objects.filter(title1))
    test_instance = Author.objects.all()
    proxy4 = self.assertQuerySetEqual(Author.objects.all(), map(repr, [test_instance]))

我正在尝试比较字段标题和标题 1。但是,当尝试运行上面的代码时,我不断得到一个“视图”对象没有属性“assertQuerysetEqual”。我什至无法让这个功能工作。我运行 Django 1.11 和 Postgresql。也许这个功能不适用于 Postgresql?感谢任何帮助我走上正轨的帮助。一直在玩这个并研究了一上午,没有运气。提前致谢。

更新...我也一直在尝试比较视图中的 title_set.all 和 title1_set.all 的各种版本...。这是间歇性工作...但两者总是返回它们是相等的.

【问题讨论】:

    标签: django python-3.x django-views django-queryset


    【解决方案1】:

    self.assertQuerySetEqual 大约是unit-testing

    您只需要比较视图中的两个列表即可。可以用集合来完成。

    set(title) == set(title1)
    

    【讨论】:

    • 感谢您的建议。我仍在为如何将其合并到基于类的视图中而苦苦挣扎。我可以用函数视图来解决这个问题......但是关于如何在基于类的 DetailView 中做到这一点的想法?
    【解决方案2】:

    您的AuthorDetailView 需要继承自django.test.TestCase 才能访问self.assertQuerySetEqual,这是一项测试功能。

    所以基本上你需要像这个例子那样做:

    from django.test import TestCase
    ...
    
    class AuthorDetailView(DetailView, TestCase):
        ...
    

    否则,您可以使用set() 来比较两个列表,就像@Daniil Mashkin 在他的回答中所说的那样。

    因此,更深入地讲,您可以执行以下操作:

    class AuthorDetailView(DetailView):
        model = Author 
    
    def get_context_data(self, **kwargs):
        context = super(AuthorDetailView, self).get_context_data(**kwargs)
        title = list(Author.objects.all().values_list('title'))
        title1 = list(Author.objects.all().values_list('title1'))
        # test if the two lists are equal
        equal_ = set(title) == set(title1)
        # add the result to the context variable
        context.update({'titles_are_equal': equal_})
        # return it in order to get the variable `title_are_equal` 
        # into your template
        return context
    

    欲了解更多信息,请访问django official documentaiton

    【讨论】:

    • 所以我正在尝试在生产中执行此操作,测试所讨论的两个字段的值是否相同。这只是应该用于测试还是可以在生产中使用它?
    • @SteveSmith,不仅在测试中。在生产中使用 set() 然后在视图或模板中添加其余的比较逻辑。测试服仅用于测试环境以在投入生产之前捕获错误。
    • 上面的代码有效。对于我的用例,我需要将 title = list(Author.objects.all().values_list('title')) 更改为 Author.objects.filter(id=self.object.pk).values_list('title' )) 然后它按我的需要工作。感谢 Chiheb Nexus!
    猜你喜欢
    • 2013-04-10
    • 2016-09-03
    • 2017-12-16
    • 2023-01-25
    • 2019-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-13
    相关资源
    最近更新 更多