咱們常由於django的自帶admin後臺功能而選擇該框架,但也由於其自動生成的特殊性而在作出特別的更改的時候束手束腳,鑑於項目已經採用了django,然後臺要求可以直接上傳富文本內容直接用於網頁顯示,定製性高,後來翻了目前較爲知名的幾款富文本編輯框,以爲仍是tinymce符合可以集成到django admin的簡便條件,可是tinymce免費版不提供圖片本地上傳的服務,因此只能本身找辦法集成圖片上傳到tinymce,如下記錄一遍說明過程。css
項目環境:
python2.7.13
django1.11.6
windows 10
該環境下建立了一個最初始的django項目,models.py中添加了一個用於測試的model,其中用於關聯富文本顯示的爲TextField字段,代碼以下:python
models.py
jquery
# -*-coding:utf-8 -*- from django.db import models # Create your models here. class TestTinymce(models.Model): title = models.CharField("標題", max_length=20, default="") content = models.TextField("文本", default="") class Meta: db_table = "test_tinymce" verbose_name = "測試" verbose_name_plural = "測試" def __unicode__(self): return self.title
以後使用命令建表,使得項目可以運行起來,並添加django admin登陸用戶名密碼等,使得項目可以進入到後臺界面,而且在admin.py中註冊,使得咱們添加的表格可以在django admin中使用起來,進入如下界面:git
此時的添加測試數據頁面,TextField字段顯示爲普通的文本域:github
tinymce官方下載爲https://www.tinymce.com/downl...ajax
下載其中的Download TinyMCE Community到本地解壓,取出其中的tinymce目錄,整個複製到django項目中你的靜態文件目錄,目前的文件目錄以下:apache
整合tinymce和django admin重要的是須要在django後臺加載的時候初始化tinymce的初始化函數,按照指定的參數生成對應的富文本框,咱們經過admin.py來加載js到對應的model處理界面:django
admin.py
json
# -*-coding:utf-8 -*- from django.contrib import admin import models # Register your models here. class TestTinymce_Admin(admin.ModelAdmin): class Media: js = [ '/static/tinymce/js/jquery.min.js', # 必須首先加載的jquery,手動添加文件 '/static/tinymce/js/tinymce/tinymce.min.js', # tinymce自帶文件 '/static/tinymce/js/tinymce/plugins/jquery.form.js', # 手動添加文件 '/static/tinymce/js/tinymce/textarea.js', # 手動添加文件,用戶初始化參數 ] admin.site.register(models.TestTinymce, TestTinymce_Admin)
其中jquery.min.js爲普通的jquery文件,版本合適便可,tinymce.min.js爲tinymce自帶文件,jquery.form.js爲手動添加,是一個form插件,支持ajax表單提交和ajax文件上傳,textarea.js是我自定義的一個js,寫的初始化對應的富文本的參數,包含指定圖片上傳的指定處理路徑。windows
textarea.js
tinymce.init({ selector: "textarea", // 選擇該頁面綁定的標籤 themes: "modern", menubar: false, convert_urls: false, height: 450, plugins: [ 'advlist autolink lists link image charmap print preview hr anchor pagebreak', 'searchreplace wordcount visualblocks visualchars code fullscreen', 'insertdatetime media nonbreaking save table contextmenu directionality', 'emoticons template paste textcolor colorpicker textpattern imagetools', "link imageupload" ], toolbar: "undo redo | imageupload link | bold italic | styleselect fontselect fontsizeselect | bullist numlist outdent indent | alignleft aligncenter alignright alignjustify | print preview media | forecolor backcolor emoticons", content_css: [ '//fast.fonts.net/cssapi/e6dc9b99-64fe-4292-ad98-6974f93cd2a2.css', '//www.tinymce.com/css/codepen.min.css' ], imageupload_url: '/upload_img/', // 指定圖片上傳處理目錄 language:'zh_CN' });
注:其中爲了顯示爲中文,標明瞭中文zh_CN,同時須要下載語言包zh_CN.js放到對應的langs文件夾下。此時,django admin中的文本域已經被富文本框代替,咱們此時只須要把對應的圖片上傳整合:
添加圖片上傳插件imageupload到plugins文件夾下,此時就符合了咱們在textarea.js中toolbar參數中添加的imageupload,同時下載jquery.form.js在符合咱們在admin.py加載的路徑放置:
此時咱們能夠看見在富文本框上指定位置出現了圖片上傳的按鈕,點擊出現上傳本地文件的按鈕:
在彈出按鈕出現以後,咱們處理imageupload_url: '/upload_img/'
上傳文件的路徑背後的視圖處理,根據django的映射規則,咱們在urls.py添加路徑:
url(r'^upload_img/$', views.upload_img), # 後臺富文本框上傳圖片
添加views.py中的處理接收上傳的函數upload_img
:
# -*-coding:utf-8 -*- from django.shortcuts import render from django.views.decorators.csrf import csrf_exempt import json import time from PIL import Image from django.conf import settings from django.http import HttpResponse # Create your views here. static_base = 'http://127.0.0.1:8000' static_url = static_base + settings.MEDIA_URL # 上傳文件展現路徑前綴 # 上傳圖片 POST @csrf_exempt def upload_img(request): file = request.FILES['file'] data = { 'error':True, 'path':'', } if file: timenow = int(time.time()*1000) timenow = str(timenow) try: img = Image.open(file) img.save(settings.MEDIA_ROOT + "content/" + timenow + unicode(str(file))) except Exception,e: print e return HttpResponse(json.dumps(data), content_type="application/json") imgUrl = static_url + 'content/' + timenow + str(file) data['error'] = False data['path'] = imgUrl return HttpResponse(json.dumps(data), content_type="application/json")
建立接收上傳的文件的文件夾,按照settings.py中的配置和指定的上傳文件目錄:
其中爲了防止回顯的時候不識別media路徑,在urlpatterns中添加以下:
from django.conf.urls import url from django.contrib import admin from app import views from django.conf import settings from django.conf.urls.static import static urlpatterns = [ url(r'^upload_img/$', views.upload_img), # 後臺富文本框上傳圖片 url(r'^admin/', admin.site.urls), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
目前功能已經所有實現,能夠看見上傳圖片成功以後回顯:
順便附上settings.py中的上傳文件和靜態文件目錄的配置:
# Internationalization # https://docs.djangoproject.com/en/1.10/topics/i18n/ LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True USE_TZ = False # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.8/howto/static-files/ STATIC_URL = '/static/' # 當運行 python manage.py collectstatic 的時候 # STATIC_ROOT 文件夾 是用來將全部STATICFILES_DIRS中全部文件夾中的文件,以及各app中static中的文件都複製過來 # 把這些文件放到一塊兒是爲了用apache等部署的時候更方便 STATIC_ROOT = os.path.join(BASE_DIR, 'collected_static') # 其它 存放靜態文件的文件夾,能夠用來存放項目中公用的靜態文件,裏面不能包含 STATIC_ROOT # 若是不想用 STATICFILES_DIRS 能夠不用,都放在 app 裏的 static 中也能夠 STATICFILES_DIRS = ( os.path.join(BASE_DIR, "common_static"), ) # 這個是默認設置,Django 默認會在 STATICFILES_DIRS中的文件夾 和 各app下的static文件夾中找文件 # 注意有前後順序,找到了就再也不繼續找了 STATICFILES_FINDERS = ( "django.contrib.staticfiles.finders.FileSystemFinder", "django.contrib.staticfiles.finders.AppDirectoriesFinder" ) ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/' MEDIA_URL = '/media/' MEDIA_ROOT = BASE_DIR + '/media/upload/'