Django ModelForm ImageField 上傳注意事項


建立時間: 2023年7月23日 17:26
更新時間: 2023年7月23日 18:12

說明

分享使用 ModelForm 上傳 ImageField 儲存到模型時,需要設定什麼。

models.py

示範新增 Article 模型,內含 cover_image ImageField 欄位。

upload_to 需自己設定儲存路徑。

models.py

from django.db.models import Model

class Article(Model):
    """文章"""

    # 封面圖片
    cover_image = ImageField(upload_to="your_image_path", blank=True)

forms.py

示範表單上傳 Article 模型,包含 cover_image 圖像欄位。

注意 from my_app.models import Article,填入你的 models 位置和名稱。

forms.py

from django.forms import ModelForm

from my_app.models import Article


class ArticleForm(ModelForm):
    """文章表單"""

    class Meta:
        model = Article
        fields = ["cover_image"]
        labels = {
            "cover_image": "封面照片",
        }

view.py

article_id 是從網址取得的 id,一開始會先檢查 id 是否有文章,接著檢查 HTTP 請求是 GET 還是 POST,GET 的話只需帶入空表單給前端渲染就好,如果是 POST 就檢查表單是否有效,無效的話就必須傳給前端修改,有效才寫入到資料庫。

view.py

"""文章編輯"""

from django.http import HttpRequest
from django.http import HttpResponse
from django.shortcuts import redirect
from django.shortcuts import render

from my_app.forms import ArticleForm
from my_app.models import Article


def article_edit(request: HttpRequest, article_id: int) -> HttpResponse:
    """文章編輯

    Args:
        request (HttpRequest): Http 請求

    Returns:
        HttpResponse: Http 回應
    """

    try:
        article: Article = Article.objects.get(id=article_id)
    except Article.DoesNotExist:
        return redirect("index")

    if request.method == "GET":
        # 空表單
        article_form = ArticleForm(instance=article)

        return render(
            request,
            "my_app/article_edit.html",
            {
                "article_form": article_form,
                "article_id": article_id,
            },
        )

    if request.method == "POST":
        # 表單包含使用者輸入的資料
        article_form = ArticleForm(request.POST, request.FILES, instance=article)

        # 表單無效
        if not article_form.is_valid():
            return render(
                request,
                "my_app/article_edit.html",
                {
                    "article_form": article_form,
                    "article_id": article_id,
                },
            )

        article_form.save()

        # 成功寫入重新導向網址
        return redirect("your_url")

    # 未知的特殊狀況
    return redirect("your_url")

注意 ArticleForm(request.POST, request.FILES, instance=article) 這行,第1個參數是請求的資料,這個比較常見,需注意第2個參數是檔案,如果沒帶入第2個參數,就沒辦法取得圖片檔案。

HTML

這裡假設 url 處理文章表單的名稱是 article_edit

article_formarticle_id 是從 view 設定的變數。

article_edit.html

<form action="{% url 'article_edit' article_id %}"
      enctype="multipart/form-data"
      method="post"
      name="article_edit">
    {% csrf_token %}
    {{ article_form.as_p }}
    <button type="submit" class="btn btn-primary">儲存</button>
</form>

需注意 form 表單屬性要加上 enctype="multipart/form-data"

url

示範 article edit url

path('article_edit/<int:article_id>', view.article_edit, name='article_edit')

觀看次數: 917
ImageFieldModelFormdjangofieldformimagemodel
按讚追蹤 Enjoy 軟體 Facebook 粉絲專頁
每週分享資訊技術

一杯咖啡的力量,勝過千言萬語的感謝。

支持我一杯咖啡,讓我繼續創作優質內容,與您分享更多知識與樂趣!