1 这一章主要介绍富文本编辑器文件的上传
步骤:
(one) 配置上传的文件路径
1 在根目录下面创建一个uploads的文件夹,存放上传的文件
2 在settings.py中设置MEDIA_URL 和MEDIA_ROOT,如下
MEDIA_URL = '/uploads/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')
MEDIA_ROOT 代表着 要上传的路径会和你在models中写的上传的路径进行拼节形成最终文件上传的路径,MEDIA_URL 主要就是映射了,在前端使用media_url 当你的media_root 发生改变的时候不用去更改前端模板中的内容
在settings.py的TEMPLATES 中添加一个上下文环境 ‘django.template.context_processors.media’, 这个会自动的把MEDIA_URL 注册到前端的模板中的 没有这个上下文环境 MEDIA_URL在前端是没有显示的
3 在url.py中配置路由
from django.contrib import admin
from django.urls import path, re_path
from blog.views import *
from django.views.static import serve # 专门处理静态文件的一个方法,处理完之后就会返回一个响应
from django.conf import settings
urlpatterns = [
其他代码,
re_path(r"^uploads/(?P<path>.*)$/", serve, {
'document_root': settings.MEDIA_ROOT,
}),
]
# 查看serve源码, 它需要document_root和path参数
这样就已经可以实现文件的上传了,例如上传用户的头像,注意我在定义模型类的时候,用户的头像我用了下面的语句
avatar = models.ImageField(upload_to='avatar/%Y/%m', default='avatar/default.png',
max_length=200, blank=True, null=True, verbose_name='用户头像')
# upload_to等价于 os.path.join(MEDIA_ROOT, 'avatar/%Y/%m')
(two)解决富文本编辑器文件上传的问题
富文本编辑器的文件上传相对麻烦一些
1 在需要使用富文本编辑器的model中定义meta类:
class Media:
js = (
'/static/js/kindeditor-4.1.10/kindeditor-min.js',
'/static/js/kindeditor-4.1.10/lang/zh-CN.js',
'/static/js/kindeditor-4.1.10/config.js',
)
2 在kindeditor-4.1.10目录中定义config.js文件:
这个文件是根据kindeditor官网的文档写出来的
KindEditor.ready(function(K) {
K.create('#id_content',{
width:'800px',
height:'200px',
uploadJson: '/admin/upload/kindeditor',
});
});
uploadJson是上传路径, ready 函数是js里面的,作用是加载内容, ‘#id_content’这是css选择器里面的语法,母的就是找到id_content对应的标签。
3 在urls.py中定义文件上传的处理器:
from blog.upload import upload_image
re_path(r'^admin/upload/(?P<dir_name>[^/]+)$', upload_image, name='upload_image'),
4 在settings.py中设置MEDIA_URL 和MEDIA_ROOT, 上面已经提到过
5 在应用blog下新建一个upload.py文件处理上传的一些逻辑:
from django.http import HttpResponse
from django.conf import settings
from django.views.decorators.csrf import csrf_exempt
import os
import uuid
import json
import datetime as dt
@csrf_exempt # 通过csrf_exempt, 来取消csrftoken验证
def upload_image(request, dir_name):
"""
kindeditor图片上传返回数据格式说明
{"error":1, "message": "出错错误"}
{"error":0, "message": "图片地址"}
"""
result = {"error": 1, "message": "出错错误"}
# request.FILES中的键来自于表单中的<input type="file" name="" />的name值
# request.FILES中的值均为UploadedFile类文件对象。
files = request.FILES.get('imgFile', None)
if files:
result = image_upload(files, dir_name)
return HttpResponse(json.dumps(result), content_type="application/json")
# 目录创建
def upload_generation_dir(dir_name):
today = dt.datetime.today()
dir_name = dir_name + '/%d/%d/' % (today.year, today.month)
if not os.path.exists(settings.MEDIA_ROOT + dir_name):
os.makedirs(os.path.join(settings.MEDIA_ROOT, dir_name))
return dir_name
# 图片上传
def image_upload(files, dir_name):
# 允许上传文件类型
allow_suffix = ['jpg', 'png', 'jpeg', 'gif', 'bmp']
file_suffix = files.name.split(".")[-1]
if file_suffix not in allow_suffix:
return {"error": 1, "message": "图片格式不正确"}
relative_path_file = upload_generation_dir(dir_name)
path = os.path.join(settings.MEDIA_ROOT, relative_path_file)
if not os.path.exists(path): # 如果目录不存在创建目录
os.makedirs(path)
# uuid1() 由MAC地址、当前时间戳、随机数生成。可以保证全球范围内的唯一性,
file_name = str(uuid.uuid1()) + "." + file_suffix
path_file = os.path.join(path, file_name)
file_url = settings.MEDIA_URL + relative_path_file + file_name
open(path_file, 'wb').write(files.file.read())
return {"error": 0, "url": file_url}
上传成功
不足之处, 欢迎批评指正,thanks!