Django REST Framework 图片上传app完整指南
以下是一个通过 Django REST Framework (DRF) 实现图片上传功能的完整示例,涵盖从环境配置到功能实现的所有步骤,同时增加了功能点和知识点的解析,便于理解与扩展。
功能点
- 图片上传功能:实现通过 API 接口上传图片并保存到服务器。
- 文件大小与类型验证:限制上传的图片大小和文件类型。
- 图片存储路径设置:将图片保存到自定义路径,并支持本地存储与云存储扩展。
- 图片访问功能:提供图片的公开访问 URL。
- 分页功能:支持图片数据的分页展示,适合大数据量场景。
- 权限控制:为上传和访问接口添加用户权限验证。
- 图片优化:对上传图片进行压缩和尺寸调整以节省存储空间。
- 扩展与生产支持:支持在本地开发和生产环境下的配置切换。
知识点
- DRF 基础:
ModelViewSet
的使用,结合序列化器与模型完成 CRUD。 - 图片上传解析器:
MultiPartParser
和FormParser
的作用与用法。 - Django 文件存储系统:
MEDIA_URL
和MEDIA_ROOT
的配置。 - 数据验证:如何在序列化器中添加自定义验证逻辑。
- 分页设置:自定义分页类实现分页功能。
- 信号机制:使用 Django 的信号 (
post_save
) 实现图片处理。 - 安全性优化:限制文件大小和文件类型,防止恶意上传。
完整实现步骤
1. 安装依赖
在项目开始前,确保安装以下依赖库:
pip install django djangorestframework pillow
- Django:Web 框架。
- Django REST Framework (DRF):用于构建 API 的工具集。
- Pillow:Python 图像处理库,用于图片验证和处理。
2. 配置 Django 项目
-
创建 Django 项目与应用:
django-admin startproject myproject cd myproject python manage.py startapp myapp
-
配置
settings.py
:-
添加
INSTALLED_APPS
:INSTALLED_APPS = [ ... 'rest_framework', 'myapp', ]
-
配置媒体文件路径:
import os MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
-
-
配置
urls.py
:
在项目的myproject/urls.py
中添加媒体文件支持:from django.conf import settings from django.conf.urls.static import static urlpatterns = [ ... ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
3. 创建模型
在 myapp/models.py
中创建用于存储图片的模型:
from django.db import models
class ImageUpload(models.Model):
image = models.ImageField(upload_to='images/') # 指定存储路径
uploaded_at = models.DateTimeField(auto_now_add=True) # 自动记录上传时间
def __str__(self):
return self.image.name
功能点:
upload_to='images/'
:指定图片上传的目录为media/images/
。uploaded_at
:记录图片的上传时间。
4. 创建序列化器
在 myapp/serializers.py
中创建一个序列化器:
from rest_framework import serializers
from .models import ImageUpload
class ImageUploadSerializer(serializers.ModelSerializer):
class Meta:
model = ImageUpload
fields = ['id', 'image', 'uploaded_at']
def validate_image(self, value):
# 验证文件类型
if not value.content_type.startswith('image/'):
raise serializers.ValidationError('Uploaded file is not a valid image.')
# 验证文件大小
if value.size > 5 * 1024 * 1024: # 限制大小为5MB
raise serializers.ValidationError('Image size should not exceed 5MB.')
return value
知识点:
validate_<field_name>
方法用于对字段值进行自定义验证。- 可以通过
content_type
验证文件类型,通过size
限制文件大小。
5. 创建视图
在 myapp/views.py
中创建图片上传接口的视图:
from rest_framework import viewsets
from rest_framework.parsers import MultiPartParser, FormParser
from .models import ImageUpload
from .serializers import ImageUploadSerializer
class ImageUploadViewSet(viewsets.ModelViewSet):
queryset = ImageUpload.objects.all().order_by('-uploaded_at') # 按上传时间倒序
serializer_class = ImageUploadSerializer
parser_classes = (MultiPartParser, FormParser) # 处理文件上传的解析器
知识点:
MultiPartParser
和FormParser
:处理多部分表单数据,适用于文件上传。ModelViewSet
:提供标准的 CRUD 操作,减少代码量。
6. 配置 URL
在 myapp/urls.py
中注册路由:
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ImageUploadViewSet
router = DefaultRouter()
router.register(r'images', ImageUploadViewSet) # 注册路由
urlpatterns = [
path('', include(router.urls)),
]
7. 数据库迁移
运行以下命令创建和迁移数据库:
python manage.py makemigrations
python manage.py migrate
8. 运行开发服务器
启动开发服务器进行测试:
python manage.py runserver
9. 测试图片上传
-
使用 cURL 测试:
curl -X POST http://127.0.0.1:8000/api/images/ -F "image=@/path/to/image.jpg"
-
使用 Postman 测试:
- 设置请求方法为
POST
。 - URL 为
http://127.0.0.1:8000/api/images/
。 - 在表单数据中添加
image
字段并上传图片。
- 设置请求方法为
10. 访问上传的图片
上传成功后,可以通过以下 URL 访问图片:
http://127.0.0.1:8000/media/images/<image-name>
附加优化
-
分页设置:
在settings.py
中全局配置分页:REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 10, # 每页显示 10 条记录 }
-
图片处理:
对上传图片进行压缩或缩放:from PIL import Image def resize_image(image, max_width=800, max_height=800): with Image.open(image) as img: img.thumbnail((max_width, max_height)) img.save(image.path, optimize=True, quality=85)
在模型保存后调用:
from django.db.models.signals import post_save from django.dispatch import receiver @receiver(post_save, sender=ImageUpload) def process_image(sender, instance, **kwargs): resize_image(instance.image)
-
权限控制:
限制接口访问权限:from rest_framework.permissions import IsAuthenticated class ImageUploadViewSet(viewsets.ModelViewSet): permission_classes = [IsAuthenticated]
通过以上步骤,你将实现一个功能完整且安全的图片上传 API,同时具备高可扩展性,支持未来在生产环境中的部署与优化。
标签:app,py,Apps,Django,import,上传,image,图片 From: https://blog.csdn.net/qq_59344127/article/details/145153687