在 Django 中处理原始查询

Salman Mehmood 2022年7月18日
在 Django 中处理原始查询

通过这个解释,我们将了解 raw() 方法的作用以及我们如何操作原始查询,我们还将学习如何在 Django 的应用程序中注入 SQL。

借助 Django 中的 raw() 方法处理原始查询

在 Django 中使用 raw() 方法允许我们获取或构建 SQL 查询并执行它们。但这不是在 Django 中运行 SQL 查询的唯一方法;除了使用默认的表单设置,如果我们愿意,我们还可以绕过表单并只运行 SQL 查询。

但我们为什么提到这一点?因为当你想要执行原始 SQL 查询时,模型管理器 raw() 方法通常应该是你的首选。

这是因为原始查询集类实例的结构与你一直在使用的查询集类实例的结构非常相似。我们可以在原始查询中执行其他操作,例如索引和切片。

所以让我们从一个非常简单的例子开始。让我们继续创建名为 STUDENT_DATA() 的新函数。

我们将在 models.py 文件中使用简单数据集和 Student 模型。

class Student(models.Model):

    FIRST_NAME = models.CharField(max_length=100)
    SR_NAME = models.CharField(max_length=100)
    age = models.IntegerField()
    CLASS_ROOM = models.IntegerField()
    TEACHER = models.CharField(max_length=100)

    def __str__(self):
        return self.FIRST_NAME

现在我们将回到 views.py 文件并创建一个名为 STUDENT_DATA() 的函数来演示原始 SQL。

在函数内部,我们将使用 Student.objects.all() 从 Student 表中获取所有数据。这将返回该表中的所有学生数据并将其存储在 SD_DATA 中。

让我们打印这个对象。我们还将使用 connection.queries,它将给出 SQL 的输出和一些性能测量。

def STUDENT_DATA(request):

    SD_DATA = Student.objects.all()

    print(SD_DATA)
    print(connection.queries)
    return render(request,'output.html',{'data': SD_DATA})

让我们继续运行服务器。浏览器会显示所有数据,然后在下面,我们可以看到我们得到了我们执行的 SQL 查询。

Django 原始 SQL 输出 1

让我们继续使用 raw() 方法创建一个等价物。因此,我们将再次使用 student 及其对象,但这次我们将使用 raw()

我们需要在这个方法中运行 SQL 查询:SELECT * FROM student_student

我们不需要选择所有这些单独的项目,因此我们可以使用星号选择所有表字段,然后下一个子句是 FROM,这有助于查找表。然后我们将定义名为 student_student 的表名。

SD_DATA = Student.objects.raw('SELECT * FROM student_student')

让我们回到浏览器并刷新它。然后我们将看到我们正在使用 Select 语句从数据库中返回这些项目。

Django 原始 SQL 输出 2

现在我们将继续前进并稍微扩展它并选择一个单独的项目。为此,我们需要使用 WHERE 子句;在一个空格之后,我们选择 age 属性并将其作为值 21 传递。

SD_DATA = Student.objects.raw('SELECT * FROM student_student WHERE age=21')

让我们重新运行 Django 服务器并刷新浏览器。然后我们将看到 SQL 正在运行并从数据库中返回一个项目。

Django 原始 SQL 输出 3

我们已经看到了如何将我们的 SQL 注入 Django 的 raw() 函数,以及我们如何对数据库执行操作。

在 Django 文档中,如果你查看模型即时参考并通读,它将为你提供有关延迟模型的一些信息。术语延迟模型实例是指从查询发出的字段,直到我们按需加载它们。

要打印数据,我们需要指定要在输出中看到的数据,为此,我们需要使用 for 循环。

for d in Student.objects.raw('SELECT * FROM student_student'):
        print(d)

如果我们重新运行它,请查看控制台,因为我们正在打印它并从表中返回三个名称。

Django 原始 SQL 输出 4

你可以在此处找到更复杂的查询。例如,一个叫做制作查询集的概念意味着我们可以限制我们想要返回的对象的数量。

现在我们将声明一个名为 sql 的新变量,然后在其中存储 SQL 查询并将其传递给 raw() 函数。在 raw() 函数之后,我们将通过切片对象来限制两行。

sql='SELECT * FROM student_student'
SD_DATA = Student.objects.raw(sql)[:2]

当我们查看输出时,它只是返回两行。

Django 原始 SQL 输出 5

views.py 文件的完整源代码:

from django.shortcuts import render
from .models import Student
from django.db import connection


def STUDENT_DATA(request):

    SD_DATA = Student.objects.all()
    sql='SELECT * FROM student_student'
    SD_DATA = Student.objects.raw(sql)[:2]
    # for d in Student.objects.raw('SELECT * FROM student_student'):
    #     print(d)

    print(SD_DATA)
    # print(connection.queries)
    return render(request,'output.html',{'data': SD_DATA})

我们在模板中使用了以下代码。

{{data}}

<hr/>

{% for i in data %}
    <div>{{ i.FIRST_NAME }} - {{ i.age }}</div>
{% endfor %}
Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn