Django - 遵循反向关系的两种不同方法
Posted
技术标签:
【中文标题】Django - 遵循反向关系的两种不同方法【英文标题】:Django - two different methods of following reverse relations 【发布时间】:2014-02-22 10:56:08 【问题描述】:基于此页面上的示例:https://docs.djangoproject.com/en/dev/topics/db/queries/
class Blog(models.Model):
name = models.CharField(max_length=100)
class Entry(models.Model):
blog = models.ForeignKey(Blog)
headline = models.CharField(max_length=255)
我想查找博客名称为 hello world
的所有条目。有两种方法可以做到这一点。数据库性能方面有什么区别?其中一个更好/更受欢迎吗?
b = Blog.objets.get(name='hello world')
b.entry_set.all()
或
Entry.objects.filter(blog__name='hello world')
【问题讨论】:
Blog.objects.get(name='hello world') 可能会导致异常 Blog.DoesNotExist 好的,谢谢你的提示。 【参考方案1】:第一个方法是两个独立的数据库调用:一个是查找 Blog,第二个是获取 Entry 对象。但是,每个都是没有 JOIN 的简单查询。
第二种方法只是一个查询,但会执行一个 JOIN 来查找与带有该 slug 的博客相关的条目。
您使用哪种方法取决于您的用例。例如,如果您已经拥有博客,那么直接在其上调用entry_set
会更好,因为那只是一个简单的查询。而如果您知道博客 ID 而不是 slug,那么最好使用 Entry.objects.filter(blog_id=my_blog_id)
,因为这样您根本就没有进行 JOIN,所以还是一个简单的查询。
【讨论】:
谢谢,更新了我的答案以反映这两种方法的效果。【参考方案2】:我是这样比较的
q1 = Blog.objects.get(name='hello world').entry_set.all()
q2 = Entry.objects.filter(blog__name='hello world')
print q1.query
SELECT `entry`.`id`, `entry`.`blog_id` FROM `entry` WHERE `entry`.`blog_id` = 1
print q2.query
SELECT `entry`.`id`, `entry`.`blog_id` FROM `entry` INNER JOIN `blog` ON ( `entry`.`blog_id` = `blog`.`id` ) WHERE `blog`.`name` = 'hello world'
此外,正如@crazyzubr 所指出的,如果找不到对象或找到多个对象,q1 将引发异常。
【讨论】:
以上是关于Django - 遵循反向关系的两种不同方法的主要内容,如果未能解决你的问题,请参考以下文章