在 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.