目录
一、简介
二、DRF
①Settings文件配置
②Urls文件配置
③Models文件
④Views文件
三、VUE
①router
②views
本篇文章主要用于介绍如何使用VUE+DRF实现用户头像上传
在DRF框架下如果想要实现文件的上传,需要配置媒体文件的目录与路由,具体配置如下:
# zero_demo/settings.py
# 媒体文件目录
from pathlib import Path
import os
BASE_DIR = Path(__file__).resolve().parent.parent
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
# 上传文件目录
UPLOAD_PATH = 'upload/'
# 访问媒体文件的路由
MEDIA_URL = '/media/'
settings文件最后一行代码配置了访问媒体文件的路由,这是不够的,还需要在urls文件中配置具体的路由,其配置如下:
# zero_demo/urls.py
from django.urls import re_path
from django.views.static import serve
from django.conf import settings
urlpatterns = [
re_path(r"^media/(?P.*)$", serve, {'document_root': settings.MEDIA_ROOT}, name='media'),
]
配置好settings和urls文件之后,在数据库中创建一张用户表,用于存储与用户有关的所有信息,models文件代码如下:
class Admin(models.Model):
""" 用户表 """
user = models.CharField(verbose_name="用户名", max_length=32)
password = models.CharField(verbose_name="密码", max_length=32)
head = models.CharField(verbose_name="头像路径", max_length=128)
最后则是在Views文件中实现上传头像的逻辑,大致是思路是编写一个API接口提供给前端VUE界面发送POST请求,然后将上传的图片存储与media目录下,接着返回存储与media目录下的url给前端,以供前端通过url找到存储在media目录下的图片进行展示 ,具体代码实现如下:
序列化器
# apps/rbac/views.py
class AdminSerializer(serializers.ModelSerializer):
role_display = AdminRoleSerializer(many=True, source='roles', read_only=True)
# 使用自定义钩子方法,返回带前缀的url
head_url = serializers.SerializerMethodField()
class Meta:
model = models.Admin
fields = "__all__"
def get_head_url(self, obj):
# 调用request中的build_absolute_uri方法,返回带前缀的url
return self.context['request'].build_absolute_uri(obj.head)
View类
这里调用了@action方法,它的作用可以让在调用AdminView的url的后面增加新的url,例如/api/rbac/admin/这个url调用了AdminView,它的后面会多增加一个/api/rbac/admin/upload/的url
from rest_framework.decorators import action
class AdminView(ModelViewSet):
authentication_classes = []
permission_classes = []
queryset = models.Admin.objects.all()
serializer_class = AdminSerializer
def get_serializer_class(self):
if self.request.method == "POST":
return AdminCreateSerializer
return AdminSerializer
# detail=False的意思是生成的额外url不用带id
@action(detail=False, methods=['post'], url_path="upload")
def upload(self, request):
upload_object = request.FILES.get("file")
# upload_object.size # 文件大小
# upload_object.name # 文件名称
# upload_object.read() # 读取整个文件
# for chunk in upload_object.chunks(1024): # 每次读取1024字节的文件
# pass # 读取内容写入到本地
if upload_object.size > 1 * 1024 * 1024:
return Response({
"code": 444,
"msg": "文件太大"
})
upload_url = get_upload_filename(upload_object.name)
save_path = default_storage.save(upload_url, upload_object)
local_url = default_storage.url(save_path)
abs_url = request.build_absolute_uri(local_url)
context = {
'data': {
'url': local_url,
'abs_url': abs_url
}
}
# 返回本地路径
return Response(context)
上面的代码中调用了get_upload_filename方法
upload_url = get_upload_filename(upload_object.name)
其定义如下:
# apps/rbac/views.py
from datetime import datetime
from django.conf import settings
import os
from django.core.files.storage import default_storage
def get_upload_filename(file_name):
date_path = datetime.now().strftime('%Y/%m/%d')
upload_path = os.path.join(settings.UPLOAD_PATH, date_path)
file_path = os.path.join(upload_path, file_name)
return default_storage.get_available_name(file_path)
将Views文件配置完成后,后端也就算准备完成,接下来编写前端VUE代码
首先在router注册一个用户编辑的路由
# router/index.js
const routes = [
{
path: '/authEdit',
name: 'AuthEdit',
component: () => import('../views/account/AuthEditView.vue')
},
]
路由中调用了AuthEditView.vue,因此需要在编写该vue,即用户编辑的页面
个人信息编辑
返回
个人信息
-
只能上传图片文件,且不超过2M
提交修改