Django视图中的原始SQL查询

86 投票
7 回答
167661 浏览
提问于 2025-04-16 17:15

我该如何在 views.py 中使用原始 SQL 来执行以下操作呢?

from app.models import Picture

def results(request):
    all = Picture.objects.all()
    yes = Picture.objects.filter(vote='yes').count()
    return render_to_response(
        'results.html', 
        {'picture':picture, 'all':all, 'yes': yes}, 
        context_instance=RequestContext(request)
    )

这个 results 函数会是什么样子的呢?

7 个回答

12

如果你使用的是PostgreSQL数据库,可以通过一个查询就完成这个操作。如果不是,你可以根据情况调整查询,得到想要的结果。

from django.db import connection

def results(request):
    with connection.cursor() as cursor:
        query = """
        SELECT count(*) as all_count, 
        count(*) FILTER(WHERE vote = 'yes') as yes_count
        FROM people_person;
        """
        cursor.execute(query)
        row = cursor.fetchone()
        all_count, yes_count = row
81

Django的文档真的是非常好。 你基本上有两种方法来执行原始SQL语句。你可以使用 Manager.raw() 来进行原始查询,这样会返回模型实例,或者你可以直接跳过模型层,执行自定义的SQL语句。

使用 raw() 管理器:

>>> for p in Person.objects.raw('SELECT * FROM myapp_person'):
...     print p
John Smith
Jane Jones

如果你想直接跳过模型层,可以使用 django.db.connection,它代表了默认的数据库连接:

def my_custom_sql():
    from django.db import connection, transaction
    cursor = connection.cursor()

    # Data modifying operation - commit required
    cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
    transaction.commit_unless_managed()

    # Data retrieval operation - no commit required
    cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
    row = cursor.fetchone()

    return row
125
>>> from django.db import connection
>>> cursor = connection.cursor()
>>> cursor.execute('''SELECT count(*) FROM people_person''')
1L
>>> row = cursor.fetchone()
>>> print row
(12L,)
>>> Person.objects.all().count()
12
>>> cursor.execute('''SELECT count(*) FROM people_person WHERE vote = "yes"''')
1L

使用 WHERE 子句来筛选投票为“是”的记录:

撰写回答