Python と Django での CRUD 操作 - パート 2

王林
リリース: 2024-07-25 15:17:12
オリジナル
967 人が閲覧しました

前回の記事では、Django プロジェクトのセットアップの基本を説明し、フロントエンドにリストとして表示する演習モデルを作成しました。この記事では、CRUD オペレーションの実行について詳しく説明します。馴染みのない方のために説明すると、CRUD は作成、読み取り、更新、削除の略で、基本的にデータに対して実行できる 4 つの基本的なアクションです。

アプリ フォルダーに 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 の略称であるクロスサイト リクエスト フォージェリ (Cross-Site Request Forgery) である偽造攻撃からフォームの送信を保護するのに役立ちます。ユーザー セッションごとに一意のトークンが生成され、サードパーティのサイトからアクセスできないため、不正な変更が行われるのを防ぎます。

私たちのフォームには、演習モデルのスキーマに従って、2 つの入力フィールドが含まれています。1 つはタイトル用、もう 1 つは日付用です。フォームが送信されると、タイトルと日付の値が POST リクエストを介して / エンドポイントに送信され、app/views.py のインデックス ビューによって処理されます。

モデル

Django では、CRUD 操作に対応する特定のメソッドを追加することで、演習モデル (本質的には 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 class メソッドを作成したときに、request.POST.get('title') を使用したことに気づいたかもしれません。これは POST リクエストでは機能しますが、リクエスト オブジェクトで使用できる PUT メソッドや DELETE メソッドはありません。

しかし、POST リクエストと PUT リクエストはどのように区別すればよいのでしょうか?前に作成したフォームを確認すると、送信ボタンに name 属性が割り当てられていることがわかります。この属性には、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 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート