首頁 >後端開發 >Python教學 >Python 和 Django 中的 CRUD 操作 - 第 2 部分

Python 和 Django 中的 CRUD 操作 - 第 2 部分

王林
王林原創
2024-07-25 15:17:121017瀏覽

在上一篇文章中,我們介紹了設定 Django 專案的基礎知識並創建了練習模型,我們將其以清單的形式顯示在前端。在本文中,我們將深入探討執行 CRUD 操作。對於不熟悉的人來說,CRUD 代表創建、讀取、更新和刪除 — 本質上是您可以對資料執行的四個基本操作。

現在我們已經在應用程式資料夾中設定了 API,我們只需擴展索引視圖即可處理建立、更新和刪除請求。

表格

讓我們設定一個允許使用者建立練習的表單。我們將再次使用 HTML 模板來實現此目的。首先,在 app/templates 資料夾中建立一個名為 add_exercise.html 的新模板。

<form method="POST" action="/">
    {% csrf_token %}
    <input type="text" name="title" placeholder="Enter the title" />
    <input type="date" name="date"  placeholder="Enter the date" />
    <button type="submit">Save</button>
</form>

接下來,在我們的 index.html 模板中,我們將使用以下方法包含 add_exercise.html 模板:

{% extends "base.html" %} {% block content %}
    <h2>Exercises</h2>
    {% include 'add_exercise.html' %}
...
{% endblock %}

我們在這裡使用 include 標籤,它可以提高 HTML 模板的可組合性,使我們的程式碼更易於維護和理解。如果您在瀏覽器中刷新頁面,您應該會看到表單出現在螢幕上。

Add Exercise

在我們的 HTML 中,我們使用

 方法屬性設定為 POST 且操作屬性指向 / 的標記,這與我們用來取得練習清單的端點相同。

在這種情況下,csrf_token 是由隨機產生的秘密值所表示的安全功能。它有助於保護我們提交的表單免受偽造攻擊,這就是 CSRF 的意思——跨站請求偽造。為每個使用者會話產生一個唯一的令牌,第三方網站無法存取該令牌,從而防止未經授權的變更發生。

我們的表單包含兩個輸入欄位:一個用於標題,另一個用於日期,遵循我們的練習模型的架構。提交表單後,標題和日期的值將透過 POST 請求傳送到 / 端點,然後由 app/views.py 中的索引檢視進行處理。

模型

在 Django 中,我們可以透過新增與 CRUD 操作相對應的特定方法來增強我們的 Exercise 模型(本質上是一個 Python 類別)。在 app/models.py 檔案中,我們將包含以下內容:

class Exercise(models.Model):
    ...

    def create(request):
        title = request.POST.get('title')
        date = request.POST.get('date')

        exercise = Exercise.objects.create(title=title, date=date)

        return exercise

我們可以從 POST 請求存取標題和日期,如上面的程式碼所示。然後,我們可以利用 Django 內建的 ORM 來建立一個新的練習並傳回已建立的實例。

我們將利用用於檢索練習的相同索引視圖,擴展它以檢查請求方法是否為 POST。如果是這樣,我們將把請求物件傳遞給我們之前定義的類別方法。建立練習後,我們會將使用者重新導向回主頁或執行頁面刷新,確保新新增的練習出現在螢幕上。

from django.http import HttpResponseRedirect

from app import models

...

def index(request):
    if request.method == 'POST':
        models.Exercise.create(request)
        return redirect('/')

    exercises = (
        models.Exercise.objects.all().order_by("created_at")
    )
    return render(request, "index.html", context={'exercises': exercises})

現在嘗試建立一個新練習,您應該會看到它出現在清單底部。

更新練習

在在練習中加入更新功能之前,讓我們先重構一下程式碼。我們將把練習移至他們自己的模板,名為 exercise.html。

<h2>Exercises</h2>
{% include 'add_exercise.html' %}
<ul style="margin: 0; list-style: none; padding: 0">
    {% for exercise in exercises %}
        <li style="margin-top: 4px">
            {% include 'exercise.html' %}
        </li>
    {% endfor %}
</ul>

在 app/templates 資料夾中為 exercise.html 建立一個模板,我們將在其中新增以下 HTML:

<form method="POST" action="/">
    {% csrf_token %}
    <input hidden name="id" value="{{exercise.id}}" />
    <input
        type="text"
        name="title"
        value="{{exercise.title}}"
        placeholder="Enter the title"
    />
    <input
        type="date"
        name="date"
        placeholder="Enter the date"
        value="{{exercise.date | date:'Y-m-d'}}"
    />
    <button type="submit" name="update">Update</button>
</form>

我們使用

 再次標記清單中的每個練習,並為 exercise.id 新增隱藏輸入,該輸入將用於更新練習。返回瀏覽器並刷新頁面;您應該會看到清單中每個練習的表格,每個輸入都預先填充了相應的練習資料。

CRUD Operations In Python & Django - Part 2

請注意,我們沒有使用 PUT 作為表單方法;相反,我們使用 POST。這是因為視圖處理程序只能解析透過 GET 和 POST 請求發送的數據,沒有對 PUT 和 DELETE 的內建支援。當我們在 Exercise 類別中建立 create 類別方法時,您可能已經注意到我們使用了 request.POST.get('title')。雖然這適用於 POST 請求,但請求物件中沒有可用的 PUT 或 DELETE 方法。

但是我們要如何區分 POST 和 PUT 請求呢?如果您檢查我們先前建立的表單,您會注意到我們為提交按鈕指派了一個名稱屬性。我們可以使用 request.POST.get('update') 以與存取標題和日期相同的方式存取此屬性。

讓我們更新建立練習表單以包含相同的變更。

<form method="POST" action="/">
    ...
    <button type="submit" name="create">Save</button>
</form>

在我們的練習視圖中,我們將進行以下更改以區分不同的請求。

def index(request):
    if request.method == 'POST':
        create = 'create' in request.POST
        update = 'update' in request.POST

        if create == True:
            models.Exercise.create(request)
        elif update == True:
            models.Exercise.update(request)

        return redirect('/')

    exercises = (
        models.Exercise.objects.all().order_by("created_at")
    )
    return render(request, "index.html", context={'exercises': exercises})

We check for the button name and forward the request to the appropriate Exercise method accordingly.

Let's add an update class method to the Exercise model in app/models.py.

def update(request):
    id = request.POST.get('id')
    title = request.POST.get('title')
    date = request.POST.get('date')

    exercise = Exercise.objects.filter(pk=id).update(title=title, date=date)

    return exercise

To update a row in the database, we can use the update method available on the Exercise model. However, before updating, we need to ensure that we are updating the correct exercise. To do this, we filter the exercises by the primary key, which is id, and update only that specific exercise.

Delete Exercise

Similarly, we’ll add a delete button next to each exercise in the exercise.html template.

<form method="POST" action="/">
    ...
    <button type="submit" name="update">Update</button>
    <button type="submit" name="delete">Delete</button>
</form>

We’ll set delete as the value of the name attribute, and in views.py, we’ll extend the if...elif statements to handle the delete operation.

def index(request):
    if request.method == 'POST':
        create = 'create' in request.POST
        update = 'update' in request.POST
        delete = 'delete' in request.POST

        if create == True:
            models.Exercise.create(request)
        elif update == True:
            models.Exercise.update(request)
        elif delete == True:
            models.Exercise.delete(request)

        return redirect('/')

    exercises = (
        models.Exercise.objects.all().order_by("created_at")
    )
    return render(request, "index.html", context={'exercises': exercises})

And in the Exercise model, we'll add the class method delete.

def delete(request):
    id = request.POST.get('id')
    is_deleted = Exercise.objects.filter(pk=id).delete()

    if is_deleted == 1:
        return True

    return False

With this addition, we've successfully implemented CRUD operations in our Python and Django application.

Key Takeaways

  1. Django view handlers do not support PUT and DELETE requests, as they do not parse the query parameters or request body for those HTTP methods. As a result, we must rely on POST requests and differentiate between them by passing an additional field in the request body.
  2. Noticed that I'm making the POST request to the same route from which I'm fetching the exercises. This is important because if you were to create an endpoint like /api/exercises to handle requests, you would need to manage redirection manually. Otherwise, the behavior of the tag after the request is to redirect the user to the endpoint specified in the action attribute. Therefore, you will need to manually redirect the user back to the desired page, or in our case, keep the user on the same page.
from django.http import HttpResponseRedirect

def index(request):
    ...

    return redirect('/')
    # or
    return HttpResponseRedirect(request.META['HTTP_REFERER'])

In summary, by effectively managing our POST requests and ensuring proper redirection, we can create a seamless user experience while implementing CRUD operations in our Django application.

以上是Python 和 Django 中的 CRUD 操作 - 第 2 部分的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn