django有没有办法注释嵌套对象?

时间:2013-05-02 12:38:13

标签: django django-orm

我有以下情况。我有三个模型,帖子,用户和朋友。

class User(models.Model):
   name = models.CharField(max_length=100)

class Friend(models.Model):
   user1 = models.ForeignKey(User,related_name='my_friends1')
   user2 = models.ForeignKey(User,related_name='my_friends2')

class Post(models.Model):
   subject = models.CharField(max_length=100)
   user = models.ForeignKey(User)

每次我带来用户,我想带上他的朋友的数量:

User.objects.filter(name__startswith='Joe').annotate(fc=Count('my_friends1'))

这很好用。

但是,当我将用户作为Post的嵌套对象时,我想做这项工作。我正在使用select_related来最小化数据库调用,所以我想做类似的事情:

Post.objects.filter(subject='sport').select_related('user').annotate(user__fc=Count('user__my_friends1'))

但是,这会在post下创建字段user__fc,而不是post.user下的字段fc。 有没有办法实现这个功能?

2 个答案:

答案 0 :(得分:1)

您可以使用Prefetch类:

from django.db.models import Count, Prefetch

posts = Post.objects.all().prefetch_related(Prefetch('user', User.objects.annotate(fc=Count('my_friends1'))))

for post in posts:
    print(post.subject)
    print(post.user.fc)

NB:这将执行两个数据库查询(在这种情况下,Django将在Post和User之间进行联接):

'SELECT "myapp_post"."id", "myapp_post"."subject", "myapp_post"."user_id" FROM "myapp_post"


'SELECT "myapp_user"."id", "myapp_user"."password", "myapp_user"."last_login", "myapp_user"."is_superuser", "myapp_user"."username", "myapp_user"."first_name", "myapp_user"."last_name", "myapp_user"."email", "myapp_user"."is_staff", "myapp_user"."is_active", "myapp_user"."date_joined", COUNT("myapp_friend"."id") AS "fc" FROM "myapp_user" LEFT OUTER JOIN "myapp_friend" ON ("myapp_user"."id" = "myapp_friend"."user1_id") WHERE "myapp_user"."id" IN (3, 4) GROUP BY "myapp_user"."id", "myapp_user"."password", "myapp_user"."last_login", "myapp_user"."is_superuser", "myapp_user"."username", "myapp_user"."first_name", "myapp_user"."last_name", "myapp_user"."email", "myapp_user"."is_staff", "myapp_user"."is_active", "myapp_user"."date_joined"

答案 1 :(得分:0)

您可以为模型定义自定义管理器,如here所述,然后覆盖其get_queryset()方法,以便在查询时将自定义列添加到模型中。

为了将此管理器用于反向关系,您应该按照docs中的描述设置基本管理器。

另一种方法类似于this,您可以使用硬编码属性指定相关模型的管理器。