现在通过后台可以新建文章分类,并且编辑保存文章了;由于Django默认的大容量文本字段是通过一个textarea作为输入方式,所以我们还需要引入一个富文本编辑器,这里我推荐KindEditor(http://kindeditor.net/demo.php),配置简单,功能也齐全。
将下载好的静态文件放在static/路径下,查看需要加载编辑器的默认textarea的id:
可以发现,id为id_字段名,新建一个config.js用于配置编辑器参数:
KindEditor.ready(function(k) {
window.editor = k.create('#id_content', {
resizeType: 1,
allowPreviewEmoticons: false,
allowImageRemote: false,
width: '700px',
height: '400px',
});
})
然后打开admin.py,写一个配置类:
from django.contrib import admin
from web_app.models import *
class NewsAdmin(admin.ModelAdmin):
list_display = ('title', 'news_class', 'date', 'show')
class Media:
# 在管理后台的相关HTML文件中加入js文件
js = (
'/static/kindeditor/kindeditor-all-min.js',
'/static/kindeditor/lang/zh-CN.js',
'/static/kindeditor/config.js',
)
list_display表示需要在后台显示的字段;配置类写好后与相关数据模型一起注册:
admin.site.register(News, NewsAdmin)
后台效果(样式上有些小问题自行修改css文件):
编辑器自带的上传图片和文件选项还不能使用,我们需要配置一个post上传url;首先在项目settings.py内添加两个配置,设置上传文件目录:
# 上传设置
MEDIA_URL = '/static/upload/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/upload')
在app文件夹内新建一个upload.py处理文件上传:
import os
import uuid
import json
import datetime
from django.http import HttpResponse
from django.conf import settings
# 上传post请求地址
# http://127.0.0.1:8000/upload_file/?dir=media
def upload(request):
# kindeditor图片上传返回数据格式说明:
# {'error': 1, 'message': '出错信息'}
# {'error': 0, 'url': '图片地址'}
result = {'error': 1, 'message': '上传失败'}
# input type="file" 中name属性对应的值为imgFile
files = request.FILES.get('imgFile', None)
type = request.GET['dir'] # 获取资源类型
if files:
result = process_upload(files, type)
# 结果以json形式返回
return HttpResponse(json.dumps(result), content_type='application/json')
def is_ext_allowed(type, ext):
# 根据类型判断是否支持对应的扩展名
ext_allowed = {}
ext_allowed['image'] = ['jpg', 'jpeg', 'bmp', 'gif', 'png']
ext_allowed['flash'] = ['swf', 'flv']
ext_allowed['media'] = ['swf', 'flv', 'mp3', 'wav', 'wma',
'wmv', 'mid', 'avi', 'mpg', 'asf', 'rm', 'rmvb', 'mp4']
ext_allowed['file'] = ['doc', 'docx', 'xls', 'xlsx', 'ppt',
'htm', 'html', 'txt', 'zip', 'rar', 'gz', 'bz2', 'pdf']
return ext in ext_allowed[type]
def get_relative_file_path():
# 获取相对路径
dt = datetime.datetime.today()
relative_path = '%s/%s/' % (dt.year, dt.month)
absolute_path = os.path.join(settings.MEDIA_ROOT, relative_path)
print(absolute_path)
if not os.path.exists(absolute_path):
os.makedirs(absolute_path)
return relative_path
def process_upload(files, type):
dir_types = ['image', 'flash', 'media', 'file']
# 判断是否支持对应的类型
if type not in dir_types:
return {'error': 1, 'message': '上传类型不支持[必须是image,flash,media,file]'}
cur_ext = files.name.split('.')[-1] # 当前上传文件的扩展名
# 判断是否支持对应的扩展名
if not is_ext_allowed(type, cur_ext):
return {'error': 1, 'message': '扩展名不支持 %s类型不支持扩展名%s' % (type, cur_ext)}
relative_path = get_relative_file_path()
# linux中一切皆文件
file_name = str(uuid.uuid1()) + '.' + cur_ext
base_name = os.path.join(settings.MEDIA_ROOT, relative_path)
# windows中的路径以\分隔
file_full_path = os.path.join(base_name, file_name).replace('\\', '/')
file_url = settings.MEDIA_URL + relative_path + file_name
with open(file_full_path, 'wb') as f:
if files.multiple_chunks() == False: # 判断是否大于2.5M
f.write(files.file.read())
else:
for chunk in files.chunks():
f.write(chunk)
return {'error': 0, 'url': file_url}
注意返回的json数据格式不要写错,否则KindEditor编辑器上传会报错。上传的文件我们保存在static/upload目录内,有了上传处理函数后,就可以在app的url.py内配置路由了:
from web_app import upload as u
# app url 配置
urlpatterns = [
re_path(r'^$', views.index),
re_path(r'^upload_file/$', u.upload, name='upload'),
]
记得在KindEditor的参数js内(config.js)添加上传url参数:
// 上传请求路径
uploadJson: '/upload_file/',
上传图片测试:
由于Django自带CSRF验证(有兴趣的同学可以了解下:https://www.jianshu.com/p/a178f08d9389),有2种方法解决:
贴一个完整的config.js:
KindEditor.ready(function(k) {
var csrf_token = document.getElementsByName('csrfmiddlewaretoken')[0].value;
window.editor = k.create('#id_content', {
resizeType: 1,
allowPreviewEmoticons: false,
allowImageRemote: false,
// 上传请求路径
uploadJson: '/upload_file/',
width: '700px',
height: '400px',
// 处理csrf验证
extraFileUploadParams: {
csrfmiddlewaretoken: csrf_token
},
});
})
清空浏览器缓存刷新页面,现在可以成功上传图片了。
后台功能先做到这里,后面的文章简单处理下前台页面的数据展现。