用Django框架開發一個簡單的企業網站(四)
阿新 • • 發佈:2018-11-27
現在通過後臺可以新建文章分類,並且編輯儲存文章了;由於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種方法解決:
- 在settings.py內註釋掉'django.middleware.csrf.CsrfViewMiddleware',關閉CSRF驗證。
- post上傳請求頭內新增CSRF引數(推薦方法)
貼一個完整的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
},
});
})
清空瀏覽器快取重新整理頁面,現在可以成功上傳圖片了。
後臺功能先做到這裡,後面的文章簡單處理下前臺頁面的資料展現。