在 Django 中處理原始查詢

Salman Mehmood 2024年2月15日
在 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
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