如何在django风格中使用两个派生表执行内连接?

时间:2012-02-06 21:08:19

标签: python django join model inner-join

这是一个派生表:

mysql> select blog_post.id,blog_post.title from blog_post where user_id=2;
+----+--------------------------------------------------------------+
| id | title                                                        |
+----+--------------------------------------------------------------+
|  4 | This week at LWN: LCA: Addressing the failure of open source |
| 16 | title week                                               |
+----+--------------------------------------------------------------+
2 rows in set (0.00 sec)

这是另一个派生表:

mysql> select object_pk,count(*) as cnt from django_comments group by object_pk;
+-----------+-----+
| object_pk | cnt |
+-----------+-----+
| 1         |   1 |
| 2         |   1 |
| 3         |   6 |
| 4         |  13 |
+-----------+-----+
4 rows in set (0.00 sec)

首先,我需要以djanto样式创建这两个派生表,然后使用这些表进行内部联接。

这是预期的最终结果:

mysql> select blog_post.user_id,blog_post.id,blog_post.title,foo.cnt from blog_post inner join(select object_pk,count(*) as cnt from django_comments group by object_pk) as foo on blog_post.id=foo.object_pk where blog_post.user_id=2;
+---------+----+--------------------------------------------------------------+-----+
| user_id | id | title                                                        | cnt |
+---------+----+--------------------------------------------------------------+-----+
|       2 |  4 | This week at LWN: LCA: Addressing the failure of open source |  13 |
+---------+----+--------------------------------------------------------------+-----+
1 row in set (0.00 sec)

任何人都可以告诉我如何使用django orm做到这一点?

我设法以这种方式获得第二个派生表:

second = Comment.objects.values('object_pk').annotate(cnt=Count('id'))

mysql表:

mysql> describe blog_post;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| user_id  | int(11)      | NO   | MUL | NULL    |                |
| title    | varchar(100) | NO   |     | NULL    |                |
| content  | longtext     | NO   |     | NULL    |                |
| created  | date         | NO   |     | NULL    |                |
| modified | date         | NO   |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)


mysql> describe django_comments;
+-----------------+--------------+------+-----+---------+----------------+
| Field           | Type         | Null | Key | Default | Extra          |
+-----------------+--------------+------+-----+---------+----------------+
| id              | int(11)      | NO   | PRI | NULL    | auto_increment |
| content_type_id | int(11)      | NO   | MUL | NULL    |                |
| object_pk       | longtext     | NO   |     | NULL    |                |
| site_id         | int(11)      | NO   | MUL | NULL    |                |
| user_id         | int(11)      | YES  | MUL | NULL    |                |
| user_name       | varchar(50)  | NO   |     | NULL    |                |
| user_email      | varchar(75)  | NO   |     | NULL    |                |
| user_url        | varchar(200) | NO   |     | NULL    |                |
| comment         | longtext     | NO   |     | NULL    |                |
| submit_date     | datetime     | NO   |     | NULL    |                |
| ip_address      | char(15)     | YES  |     | NULL    |                |
| is_public       | tinyint(1)   | NO   |     | NULL    |                |
| is_removed      | tinyint(1)   | NO   |     | NULL    |                |
+-----------------+--------------+------+-----+---------+----------------+
13 rows in set (0.00 sec)

1 个答案:

答案 0 :(得分:0)

尝试使用queryset的“额外”方法: https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.extra

获取博客文章及其评论次数:

ctype = ContentType.objects.get_for_model(BlogPost)
blog_items = BlogPost.objects.filter(user=user_id).extra(select={
        'comment_count': """
        SELECT COUNT(*) AS comment_count
        FROM django_comments
        WHERE
            content_type_id=%s AND
            object_pk=blog_post.id
        """
        }, select_params=[ctype.pk])