Django - 跟随反向关系的两种不同方法

时间:2014-01-30 08:39:02

标签: django django-models foreign-key-relationship django-queryset django-orm

根据此页面上的示例: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()

OR

Entry.objects.filter(blog__name='hello world')

2 个答案:

答案 0 :(得分:2)

第一种方法是两个独立的数据库调用:一个用于查找Blog,第二个用于获取Entry对象。但是,每个都是一个没有JOIN的简单查询。

第二种方法只有一个查询,但是通过JOIN查找与该slug相关的博客条目。

您使用哪种方法取决于您的使用案例。例如,如果您已经拥有博客,那么直接在其上调用entry_set会更好,因为那时只有一个简单的查询。如果你知道博客ID,而不是slug,那么最好做Entry.objects.filter(blog_id=my_blog_id),因为那时你根本就没有做JOIN,所以再一次简单查询。

答案 1 :(得分:0)

我比较了这些

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将引发异常。