在 Django 中上傳檔案

Vaibhav Vaibhav 2023年1月30日
  1. 設定 Django 環境
  2. 設定 Django 專案
  3. 測試伺服器
  4. 更新 settings.py 檔案
  5. 建立模型
  6. 建立表單以上傳檔案
  7. 新增檢視
  8. 配置 urls.py 檔案
  9. 測試
在 Django 中上傳檔案

本文將帶你瞭解如何在 Django 中上傳檔案。我們將建立一個簡單的應用程式,其中包含一個簡單的表單來填寫詳細資訊並選擇一個檔案。此外,在下方的表格中顯示所有上傳的檔案。

在我們繼續之前,建議為此專案建立一個新資料夾或目錄,以使事情井井有條。

設定 Django 環境

在本教程中,我們將使用虛擬環境。使用虛擬環境不是強制性的,但為每個專案擁有一個獨特的虛擬環境是一個很好的做法。

要構建虛擬環境,我們需要一個 Python 包 virtualenv。如果你的機器上沒有它,你可以使用以下命令下載它。

pip install virtualenv

現在你已經安裝了軟體包,讓我們建立環境。

要建立環境,請執行以下命令。

virtualenv environment

environment 是我們剛剛建立的虛擬環境的名稱。此環境將在你的計算機上全域性安裝 Python 版本,並且除了預設包外沒有其他包。

要啟用此環境並使用它,請執行以下命令。

environment\Scripts\activate

現在,由於我們正在學習 Django,我們需要安裝 Django 庫。此外,由於我們正在學習上傳檔案,因此我們需要一個額外的 Python 包來處理影象 - Pillow。讓我們安裝所有依賴項。

pip install django
pip install Pillow

或者,

pip3 install django
pip3 install Pillow

請注意,在撰寫本文時,最新的 Django 版本是 3.2

設定 Django 專案

要設定 Django 專案,我們首先必須建立一個 Django 專案,建立一個應用程式,註冊該應用程式,並進行初始遷移。

要建立 Django 專案,請執行以下命令。

django-admin startproject DjangoFileUpload

現在,使用以下命令將工作目錄更改為此專案。

cd DjangoFileUpload

要在 Django 專案中建立應用程式,請執行以下命令。

django-admin startapp Core

或者,

python manage.py startapp Core

Core 是應用程式的名稱。

要註冊此應用程式,請在 settings.py 檔案的 INSTALLED_APPS 列表中輸入應用程式的名稱。

  • settings.py
INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "Core",  # Here
]

Django 需要一些模型才能正常工作。例如,如果沒有初始遷移,身份驗證系統或超級使用者將無法工作。因此,要進行初始遷移,請執行以下命令。

python manage.py migrate

輸出:

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK

測試伺服器

要執行伺服器,請使用以下命令。如果一切正常,你應該會看到你的 Django 伺服器在 http://127.0.0.1:8000/ 執行。

python manage.py runserver

更新 settings.py 檔案

上傳的檔案需要儲存在某個地方。在 Django 中,預設情況下,所有上傳的檔案都儲存在 media 資料夾中。你可以隨時更改資料夾的名稱和與之關聯的 URL,但我們將堅持預設命名約定。

要定義媒體檔案的 URL MEDIA_URL 和媒體資料夾的路徑 MEDIA_ROOT,請在 settings.py 檔案中新增以下語句。

  • settings.py
import os

MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")

不要忘記匯入 os 模組。否則,Python 會丟擲錯誤。

建立模型

為了儲存上傳的檔案,我們必須建立一個模型。此模型中的欄位將儲存上傳檔案的路徑,但不儲存檔案本身。

我們將建立一個模型 Document 來儲存有關上傳檔案的詳細資訊。

  • Core\models.py
from django.db import models


class Document(models.Model):
    title = models.CharField(max_length=200)
    uploadedFile = models.FileField(upload_to="Uploaded Files/")
    dateTimeOfUpload = models.DateTimeField(auto_now=True)

該模型有一個字元型別的 title 欄位來儲存上傳檔案的自定義標題,而 dateTimeOfUpload 將儲存檔案上傳的日期和時間。日期時間欄位將在建立模型物件時自動設定。

為了儲存檔案,我們使用 FileField()。這種型別涵蓋所有型別的檔案。但是,如果你希望對影象更具體一些,則可以使用 ImageField() 來儲存影象。對於所有其他欄位,你必須堅持使用 FileField()

upload_to 引數用於定義資料夾,此模型的檔案將在其中上傳到 media 資料夾。

在我們使用這個模型之前,我們必須進行遷移並遷移它們。為此,請執行以下兩個命令。

python manage.py makemigrations
python manage.py migrate

建立表單以上傳檔案

Core 應用程式或資料夾中,建立一個新資料夾,即 templates。在此資料夾中,建立另一個資料夾,即 Core。這應該是你的應用程式的名稱。最後,在此資料夾中建立一個新檔案,即 upload-file.html

現在你應該有一個這樣的檔案結構。

DjangoFileUpload/
    DjangoFileUpload/
        __init__.py
        asgi.py
        settings.py
        urls.py
        wsgi.py
    db.sqlite3
    manage.py
    Core/
        migrations/
        templates/
            Core/
                upload-file.html
        __init__.py
        admin.py
        apps.py
        models.py
        tests.py
        views.py

upload-file.html 中,新增以下 HTML。

  • Core\templates\Core\upload-file.html
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Django File Upload</title>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');

        * {
            font-family: "Roboto";
        }

        body {
            background-color: #F5F5F5;
        }

        form {
            background-color: #FFFFFF;
            padding: 25px;
        }

        table {
            width: 100%; 
            text-align: center;
            margin-top: 25px;
            padding: 25px;
            background-color: #FFFFFF;
        }

        table tr td {
            padding-top: 15px;            
        }
    </style>
</head>
<body>
    <form action="{% url 'Core:uploadFile' %}" method="POST" enctype="multipart/form-data">
        <input type="text" name="fileTitle" placeholder="Enter a title">
        <input type="file" name="uploadedFile">
        {% csrf_token %}
        <input type="submit" value="Upload">
    </form>
    <table>
        <tr>
            <th>ID</th>
            <th>Title</th>
            <th>File Path</th>
            <th>Upload Date & Time</th>
        </tr>
        {% for file in files %}
            <tr>
                <td>{{ file.id }}</td>
                <td>{{ file.title }}</td>
                <td>{{ file.uploadedFile.url }}</td>
                <td>{{ file.dateTimeOfUpload }}</td>
            </tr>
        {% endfor %}
    </table>
</body>
</html>

在表格內,我們將顯示有關上傳檔案的一些詳細資訊。

新增檢視

為了顯示 HTML 模板及其上的資訊並儲存和處理檔案上傳,我們將建立一個檢視 uploadFile()

參考以下程式碼

  • Core\views.py
from . import models
from django.shortcuts import render


def uploadFile(request):
    if request.method == "POST":
        # Fetching the form data
        fileTitle = request.POST["fileTitle"]
        uploadedFile = request.FILES["uploadedFile"]

        # Saving the information in the database
        document = models.Document(title=fileTitle, uploadedFile=uploadedFile)
        document.save()

    documents = models.Document.objects.all()

    return render(request, "Core/upload-file.html", context={"files": documents})

該檢視呈現我們剛剛在上一節中建立的 HTML 模板。HTML 模板中的表單提交到相同的 URL 並在此檢視中處理。如果請求的方法是 POST,我們獲取表單中輸入的資訊和上傳的檔案,將該資訊儲存在模型中並儲存模型。

否則,在一般情況下,我們獲取所有上傳的檔案並將它們傳送到上下文字典中以顯示在 HTML 模板上。

配置 urls.py 檔案

最後,讓我們設定 URL。在我們繼續之前,在 Core 應用程式或資料夾中建立一個新檔案,即 urls.py。此檔案將儲存與此 Django 應用程式關聯的所有 URL。為每個 Django 應用程式都有一個單獨的 urls.py 檔案是一個很好的做法。

在此檔案中,新增以下程式碼。

from . import views
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static

app_name = "Core"

urlpatterns = [
    path("", views.uploadFile, name="uploadFile"),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

我們為 HTML 模板 upload-file.html 新增了一個 URL 模式。此外,我們還為媒體檔案新增了一個 URL。我們將使用我們在 settings.py 檔案中宣告的常量變數。

由於我們在 Core 應用程式中建立了一個新的 urls.py 檔案,我們必須將此處定義的 URL 與主專案連結起來。

為此,請在 DjangoFileUpload\urls.pyurlpatterns 列表中新增以下語句

path("", include("Core.urls")),

你的檔案應如下所示。

檔案:DjangoFileUpload\urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path("admin/", admin.site.urls),
    path("", include("Core.urls")),
]

測試

恭喜!現在是測試專案的時候了。請按照以下步驟操作。

  • 使用命令啟動伺服器 - python manage.py runserver
  • 轉到 URL http://127.0.0.1:8000/
  • 用標題填寫表單,選擇一個檔案,然後提交表單。

現在,你應該會在表單下方的表格中看到有關該檔案的一些詳細資訊。

此外,如果你檢查你的工作目錄,你會看到一個名為 media 的資料夾已經建立,在這個資料夾中,還有另一個名為 Uploaded Files 的資料夾。該資料夾包含所有上傳的檔案。

你可以上傳照片、視訊、程式、PDF、JSON 檔案、HTML 檔案等。請注意,上傳時間取決於檔案的大小,因此上傳時請耐心等待。

作者: Vaibhav Vaibhav
Vaibhav Vaibhav avatar Vaibhav Vaibhav avatar

Vaibhav is an artificial intelligence and cloud computing stan. He likes to build end-to-end full-stack web and mobile applications. Besides computer science and technology, he loves playing cricket and badminton, going on bike rides, and doodling.