【问题标题】:expanding the SQL query inside managers in Django models?在 Django 模型的管理器中扩展 SQL 查询?
【发布时间】:2014-07-21 21:12:06
【问题描述】:

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

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 来自哪里?我了解 ResponseOpinionPollforeignKey 关系。为了加入 OpinionPoll 表和 Response 表,我需要加入他们的 id。 Hwever 要访问 Response 中的投票 id,我会使用 r.poll.id。 是语法,r.poll_id,一种 MySQL 语法。

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

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

我不是 SQL 专家。如果这听起来很愚蠢,请耐心等待

编辑:

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

在 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 中完成的方式?

【问题讨论】:

  • 您是否在问如何获取现有数据库并将其转换为 django 模型?目前尚不清楚您要解决的问题是什么。
  • 不,我不是这么问的。我在问如果我在 Django 之外创建表,SQL 查询会是什么样子。我猜我上面的编辑可以更好地解释
  • 我没有得到你想要的。您是否想获取现有的 models.py,然后尝试手动创建 SQL 查询以了解查询的编写方式或什么?您的问题“我不确定这在 SQL 中是如何完成的?” - 非常令人困惑,因为您粘贴的内容 是 SQL。如果您曾经只使用过 MySQL,您可能会惊讶地发现每个数据库提供商都有自己的 SQL 风格,其中一些比其他的更严格(符合 SQL standard)。这是MySQL differs的方法。
  • 好的。我粘贴的是当我运行 sqlall myapp 时 django 吐出的 sql 语句。请暂时忘记 django。如果我想创建上面显示的两个表,我将如何在 MySQL 中执行此操作。我不清楚我是否应该明确使用REFERENCESCREATE INDEX,如上图所示,或者MYsQl 中的捷径会自动执行CREATE INDEX
  • 我认为你在谈论 manager 和 django 中的查询时让包括你自己在内的所有人都感到困惑;当您的真正问题只是“MySQL 会自动创建索引吗?” 编辑您的问题以提出您真正的问题;然后你会得到一个对你有意义的答案。

标签: mysql django django-models django-managers


【解决方案1】:

[1] Django 模型将创建像fieldname_id 这样的外键作为mysql 中的字段。所以你会看到字段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/

【讨论】:

  • 谢谢。请在上面查看我的编辑并提供帮助
  • 那将是一个 mysql 基础问题,python manage.py sqlall appname 已经告诉了你一切。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-10
  • 2017-06-07
  • 2020-08-02
  • 2011-07-09
  • 1970-01-01
  • 2019-07-05
  • 1970-01-01
相关资源
最近更新 更多