」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > Python 和 Django 中的 CRUD 操作 - 第 2 部分

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

發佈於2024-07-29
瀏覽:338

在上一篇文章中,我们介绍了设置 Django 项目的基础知识并创建了练习模型,我们将其以列表的形式显示在前端。在本文中,我们将深入探讨执行 CRUD 操作。对于那些不熟悉的人来说,CRUD 代表创建、读取、更新和删除 — 本质上是您可以对数据执行的四个基本操作。

现在我们已经在应用文件夹中设置了 API,我们只需扩展索引视图来处理创建、更新和删除请求。

表格

让我们设置一个允许用户创建练习的表单。我们将再次使用 HTML 模板来实现此目的。首先,在 app/templates 文件夹中创建一个名为 add_exercise.html 的新模板。

{% csrf_token %}

接下来,在我们的 index.html 模板中,我们将使用以下方法包含 add_exercise.html 模板:

{% extends "base.html" %} {% block content %}
    

Exercises

{% 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。

Exercises

{% include 'add_exercise.html' %}
    {% for exercise in exercises %}
  • {% include 'exercise.html' %}
  • {% endfor %}

在 app/templates 文件夹中为 exercise.html 创建一个模板,我们将向其中添加以下 HTML:

{% csrf_token %}

我们再次对列表中的每个练习使用

标签,并为 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').

让我们更新创建练习表单以包含相同的更改。

...

在我们的练习视图中,我们将进行以下更改以区分请求。

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})

我们检查按钮名称并相应地将请求转发到适当的练习方法。

让我们向 app/models.py 中的 Exercise 模型添加更新类方法。

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

要更新数据库中的行,我们可以使用 Exercise 模型上提供的更新方法。然而,在更新之前,我们需要确保我们更新的是正确的练习。为此,我们按主键 id 过滤练习,并仅更新该特定练习。

删除练习

同样,我们将在exercise.html模板中的每个练习旁边添加一个删除按钮。

...

我们将把delete设置为name属性的值,并在views.py中,我们将扩展if...elif语句来处理删除操作。

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})

在练习模型中,我们将添加类方法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

通过此添加,我们已在 Python 和 Django 应用程序中成功实现了 CRUD 操作。

要点

  1. Django 视图处理程序不支持 PUT 和 DELETE 请求,因为它们不解析这些 HTTP 方法的查询参数或请求正文。因此,我们必须依赖 POST 请求,并通过在请求正文中传递附加字段来区分它们。
  2. 注意到我正在向我从中获取练习的同一路线发出 POST 请求。这很重要,因为如果您要创建像 /api/exercises 这样的端点来处理请求,则需要手动管理重定向。否则,请求后
    标记的行为是将用户重定向到action属性中指定的端点。因此,您需要手动将用户重定向回所需页面,或者在我们的示例中,将用户保持在同一页面上。
from django.http import HttpResponseRedirect

def index(request):
    ...

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

总之,通过有效管理我们的 POST 请求并确保正确的重定向,我们可以在 Django 应用程序中实现 CRUD 操作的同时创建无缝的用户体验。

版本聲明 本文轉載於:https://dev.to/prvnbist/crud-operations-in-python-django-part-2-4fad?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何從Google API中檢索最新的jQuery庫?
    如何從Google API中檢索最新的jQuery庫?
    從Google APIS 問題中提供的jQuery URL是版本1.2.6。對於檢索最新版本,以前有一種使用特定版本號的替代方法,它是使用以下語法: https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js(google hosted...
    程式設計 發佈於2025-01-31
  • 如何使用不同數量列的聯合數據庫表?
    如何使用不同數量列的聯合數據庫表?
    合併列數不同的表 當嘗試合併列數不同的數據庫表時,可能會遇到挑戰。一種直接的方法是在列數較少的表中,為缺失的列追加空值。 例如,考慮兩個表,表 A 和表 B,其中表 A 的列數多於表 B。為了合併這些表,同時處理表 B 中缺失的列,請按照以下步驟操作: 確定表 B 中缺失的列,並將它們添加到表的...
    程式設計 發佈於2025-01-31
  • 哪種方法更有效地用於點 - 填點檢測:射線跟踪或matplotlib \的路徑contains_points?
    哪種方法更有效地用於點 - 填點檢測:射線跟踪或matplotlib \的路徑contains_points?
    在Python 射線tracing方法 matplotlib路徑對象表示多邊形。它檢查給定點是否位於定義路徑內。如提供的代碼段所示: polygon = [[np.sin(x)0.5,np.cos (x)0.5]在np.linspace中的x(0,2*np.pi,100) ] points = ...
    程式設計 發佈於2025-01-31
  • 如何限制動態大小的父元素中元素的滾動範圍?
    如何限制動態大小的父元素中元素的滾動範圍?
    在交互式界面中實現垂直滾動元素的CSS高度限制 考慮一個佈局,其中我們具有與可滾動的映射div一起移動的subollable map div用戶的垂直滾動,同時保持其與固定側邊欄的對齊方式。但是,地圖的滾動無限期擴展,超過了視口的高度,阻止用戶訪問頁面頁腳。 可以限制地圖的滾動,我們可以利用CS...
    程式設計 發佈於2025-01-31
  • 如何使用char_length()在mySQL中按字符串長度對數據進行排序?
    如何使用char_length()在mySQL中按字符串長度對數據進行排序?
    [2 using the built-in CHAR_LENGTH() function.Difference between CHAR_LENGTH() and LENGTH()CHAR_LENGTH():返回字符串中字符數的數量,考慮多字節字符編碼(例如,UTF-8)。 此查詢將從指定的表中...
    程式設計 發佈於2025-01-31
  • 對象擬合:IE和Edge中的封面失敗,如何修復?
    對象擬合:IE和Edge中的封面失敗,如何修復?
    解決此問題,我們採用了一個巧妙的CSS解決方案來解決問題: transform:translate:translate(-50%,-50%); height:100%; 高度:auto; 寬度:100%; //對於水平塊 ,使用絕對定位將圖像定位在中心,以object-fit:object-f...
    程式設計 發佈於2025-01-31
  • 如何使用PHP將斑點(圖像)正確插入MySQL?
    如何使用PHP將斑點(圖像)正確插入MySQL?
    在嘗試將image存儲在mysql數據庫中時,您可能會遇到一個可能會遇到問題。本指南將提供成功存儲您的圖像數據的解決方案。 easudy values('$ this-> ; image_id','file_get_contents($ tmp_imag...
    程式設計 發佈於2025-01-31
  • Java是否允許多種返回類型:仔細研究通用方法?
    Java是否允許多種返回類型:仔細研究通用方法?
    在java中的多個返回類型:一個誤解介紹,其中foo是自定義類。該方法聲明似乎擁有兩種返回類型:列表和E。但是,情況確實如此嗎? 通用方法:拆開神秘 [方法僅具有單一的返回類型。相反,它採用機制,如鑽石符號“ ”。 分解方法簽名: :本節定義了一個通用類型參數,E。它表示該方法接受了擴展foo類...
    程式設計 發佈於2025-01-31
  • HTML格式標籤
    HTML格式標籤
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    程式設計 發佈於2025-01-31
  • \“(1)vs.(;;):編譯器優化是否消除了性能差異?\”
    \“(1)vs.(;;):編譯器優化是否消除了性能差異?\”
    使用(1)而不是(;;)會導致無限循環的性能差異? 現代編譯器,(1)和(;;)之間沒有性能差異。 是如何實現這些循環的技術分析在編譯器中: perl: S-> 7 8 unstack v-> 4 -e語法ok 在GCC中,兩者都循環到相同的彙編代碼中,如下所示:。 globl t_時 ...
    程式設計 發佈於2025-01-31
  • 如何干淨地刪除匿名JavaScript事件處理程序?
    如何干淨地刪除匿名JavaScript事件處理程序?
    在這里工作/},false); 不幸的是,答案是否。除非在Creation中存儲對處理程序的引用。 要解決此問題,請考慮將事件處理程序存儲在中心位置,例如頁面的主要對象,請考慮將事件處理程序存儲在中心位置,否則無法清理匿名事件處理程序。 。這允許在需要時輕鬆迭代和清潔處理程序。
    程式設計 發佈於2025-01-31
  • 為什麼使用固定定位時,為什麼具有100%網格板柱的網格超越身體?
    為什麼使用固定定位時,為什麼具有100%網格板柱的網格超越身體?
    網格超過身體,用100%grid-template-columns 問題:考慮以下CSS和HTML: position:fixed ; grid-template-columns:40%60%; grid-gap:5px; 背景: #eee; 當位置未固定時,網格將正確顯示。但是...
    程式設計 發佈於2025-01-31
  • 大批
    大批
    [2 數組是對象,因此它們在JS中也具有方法。 切片(開始):在新數組中提取部分數組,而無需突變原始數組。 令ARR = ['a','b','c','d','e']; // USECASE:提取直到索引作...
    程式設計 發佈於2025-01-31
  • 如何克服PHP的功能重新定義限制?
    如何克服PHP的功能重新定義限制?
    克服PHP的函數重新定義限制在PHP中,多次定義一個相同名稱的函數是一個no-no。嘗試這樣做,如提供的代碼段所示,將導致可怕的“不能重新列出”錯誤。 // error:“ coss redeclare foo()” 但是,php工具腰帶中有一個隱藏的寶石:runkit擴展。它使您能夠靈活...
    程式設計 發佈於2025-01-31
  • PHP陣列鍵值異常:了解07和08的好奇情況
    PHP陣列鍵值異常:了解07和08的好奇情況
    PHP數組鍵值問題,使用07&08 在給定數月的數組中,鍵值07和08呈現令人困惑的行為時,就會出現一個不尋常的問題。運行print_r($月份)返回意外結果:鍵“ 07”丟失,而鍵“ 08”分配給了9月的值。 此問題源於PHP對領先零的解釋。當一個數字帶有0(例如07或08)的前綴時,PHP...
    程式設計 發佈於2025-01-31

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3