0

这是来自 django 文档的代码,它解释了管理器的使用。

class PollManager(models.Manager):
    def with_counts(self):
        from django.db import connection
        cursor = connection.cursor()
        cursor.execute("""
            SELECT p.id, p.question, p.poll_date, COUNT(*)
            FROM polls_opinionpoll p, polls_response r
            WHERE p.id = r.poll_id
            GROUP BY p.id, p.question, p.poll_date
            ORDER BY p.poll_date DESC""")
        result_list = []
        for row in cursor.fetchall():
            p = self.model(id=row[0], question=row[1], poll_date=row[2])
            p.num_responses = row[3]
            result_list.append(p)
        return result_list

class OpinionPoll(models.Model):
    question = models.CharField(max_length=200)
    poll_date = models.DateField()
    objects = PollManager()

class Response(models.Model):
    poll = models.ForeignKey(OpinionPoll)
    person_name = models.CharField(max_length=50)
    response = models.TextField()

基于此代码,我有两个问题:

1)从哪里来r.poll_id?我了解Response与OpinionPollforeignKey关系。为了将OpinionPoll表与Response表一起加入,我需要加入他们的 id。但是要访问Response中的投票 id ,我会做 r.poll.id。是语法, , 一个 MySQL 语法。r.poll_id

为什么按 p.id、p.question、p.poll_date 分组?为什么 GROUP BY p.id 单独是不够的?

2) 是否可以将上述原始 SQL 查询转换为 django ORM 查询?如果可以,那会是什么样子?

我不是一个 SQL 人。所以请耐心等待,如果这听起来很愚蠢

编辑:

如果我想在 Django 之外创建 OpinionPoll 和 Response 表,SQL 语句create会是什么样子?

在 Django shell 中,当我运行时

python manage.py sqlall appname

我得到以下信息:

BEGIN;

CREATE TABLE "myapp_opinionpoll" (
    "id" integer NOT NULL PRIMARY KEY,
    "question" varchar(200) NOT NULL,
    "poll_date" date NOT NULL
)
;
CREATE TABLE "myapp_response" (
    "id" integer NOT NULL PRIMARY KEY,
    "poll_id" integer NOT NULL REFERENCES "myapp_opinionpoll" ("id"),
    "person_name" varchar(50) NOT NULL,
    "response" text NOT NULL
)
;
CREATE INDEX "larb_response_70f78e6b" ON "myapp_response" ("poll_id");

COMMIT;

我看到类似REFERENCES "myapp_opinionpoll"CREATE INDEX以上的东西。我不确定这是否在 SQL 中是如何完成的?

4

1 回答 1

0

[1] Django 模型将创建外键,就像fieldname_idmysql 中的字段一样。因此,您会看到该字段poll = models.ForeignKey(OpinionPoll)创建了该字段。

关于GROUP BY,因为这些字段正是选择的,除了聚合函数之外,将它们准确分组可以使它们不同。

[2] 试试这个,我没有调试,但可能会有所帮助:

from django.db.models import Count
OpinionPoll.objects.annotate(num_responses=Count('response'))

有关聚合的更多信息,请参阅文档:https ://docs.djangoproject.com/en/1.6/topics/db/aggregation/

于 2014-07-21T23:18:12.417 回答