/ Django

基于Djang的文件上传接口

上传文件至服务器是比较常见的需求。在本编文章中,我们将演示使用Django-rest框架进行文件上传。

  1. 安装 virtualenv
$ pip3 install virtualenv
  1. 创建Django项目的虚拟环境。
$ virtualenv env_upload_file
Using base prefix '/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6'
New python executable in /Users/weizhen/PycharmProjects/env_upload_file/bin/python3.6
Also creating executable in /Users/weizhen/PycharmProjects/env_upload_file/bin/python
Installing setuptools, pip, wheel...done.
  1. 激活虚拟环境virtualenv

在Windows下:

$ source env_upload_file/Scripts/activate

在MacOS下:

$ source env_upload_file/bin/activate
  1. 安装django和django-restframework
$ cd env_upload_file
$ pip install django
Collecting django
  Downloading https://files.pythonhosted.org/packages/23/91/2245462e57798e9251de87c88b2b8f996d10ddcb68206a8a020561ef7bd3/Django-2.0.5-py3-none-any.whl (7.1MB)
    100% |████████████████████████████████| 7.1MB 230kB/s
Collecting pytz (from django)
  Using cached https://files.pythonhosted.org/packages/dc/83/15f7833b70d3e067ca91467ca245bae0f6fe56ddc7451aa0dc5606b120f2/pytz-2018.4-py2.py3-none-any.whl
Installing collected packages: pytz, django
Successfully installed django-2.0.5 pytz-2018.4
$ pip install djangorestframework
Collecting djangorestframework
  Downloading https://files.pythonhosted.org/packages/90/30/ad1148098ff0c375df2a30cc4494ed953cf7551fc1ecec30fc951c712d20/djangorestframework-3.8.2-py2.py3-none-any.whl (923kB)
    100% |████████████████████████████████| 931kB 340kB/s
Installing collected packages: djangorestframework
Successfully installed djangorestframework-3.8.2
  1. 创建一个名为“fileupload”的Django项目
$ django-admin startproject fileupload
$ tree fileupload
fileupload
├── fileupload
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py
  1. 进入filleupload文件夹,创建一个名为“file_app”的应用:
$ cd fileupload
$ python manage.py startapp file_app
$ tree
.
├── file_app
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── fileupload
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   └── settings.cpython-36.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

4 directories, 14 files

至此,我们已经创建了我们的项目和一个应用,下面进行相应的设置。

  1. 更新settings.py文件的‘INSTALLED_APPS’如下:
INSTALLED_APPS = [
        ...
    'rest_framework',
    'file_app',
]

并在settings.py文件末尾设置上传文件存储路径:

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
  1. 添加文件上传路径和“file_app”地址到项目文件夹下的urls.py,如下:
from django.conf.urls import url, include
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^file/', include('file_app.urls')),
]
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL,
                          document_root=settings.MEDIA_ROOT)
  1. 修改file_app/models.py
from django.db import models

class File(models.Model):
    file = models.FileField(blank=False, null=False)
    remark = models.CharField(max_length=20)
    timestamp = models.DateTimeField(auto_now_add=True)
  1. 在file_app文件夹创建serializers.py,代码如下:
from rest_framework import serializers
from .models import File


class FileSerializer(serializers.ModelSerializer):
    class Meta():
        model = File
        fields = ('file', 'remark', 'timestamp')
  1. 修改views.py如下:
from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework.response import Response
from rest_framework import status
from .serializers import FileSerializer


class FileView(APIView):
    parser_classes = (MultiPartParser, FormParser)

    def post(self, request, *args, **kwargs):
        file_serializer = FileSerializer(data=request.data)
        if file_serializer.is_valid():
            file_serializer.save()
            return Response(file_serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
  1. 在file_app下创建url.py文件
from django.conf.urls import url
from .views import FileView
urlpatterns = [
  url(r'^upload/$', FileView.as_view(), name='file-upload'),
]
  1. 测试
(env_upload_file) bogon:fileupload weizhen$ ls
file_app/  fileupload/  manage.py*
(env_upload_file) bogon:fileupload weizhen$ python manage.py makemigrations
Migrations for 'file_app':
  file_app/migrations/0001_initial.py
    - Create model File
(env_upload_file) bogon:fileupload weizhen$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, file_app, 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 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 file_app.0001_initial... OK
  Applying sessions.0001_initial... OK
(env_upload_file) bogon:fileupload weizhen$ python manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).
May 18, 2018 - 16:49:38
Django version 2.0.5, using settings 'fileupload.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[18/May/2018 16:51:12] "POST /file/upload/ HTTP/1.1" 201 104

Postman截图:

QQ20180519-005357


附注:

1.VS code提示“[pylint] E0401:Unable to import 'django.conf.urls'”,但实际上pylint已经安装。此时Python解析器应该选择虚拟环境virtualenv,及VS code的设置环境配置为:

"python.pythonPath": "${workspaceFolder}/bin/python"
  1. 原文《Uploading file using api in django rest framework》,有修改。
基于Djang的文件上传接口
Share this