HOWTO · Django

在 Django 中上传文件

了解如何在 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 文件等。请注意,上传时间取决于文件的大小,因此上传时请耐心等待。