前言
當(dāng)你寫博客上傳圖片時(shí),一定會(huì)為自己服務(wù)器空間被過多占用心生煩惱,你肯定不想本來就捉襟見肘的空間被大量圖片所占用.
大部分網(wǎng)站都會(huì)選擇把靜態(tài)資源單獨(dú)放置于對象存儲(chǔ)中單獨(dú)管理,這樣不僅提升了服務(wù)器空間利用率,也一定程度上提供了安全保證,更能提高網(wǎng)站訪問速度!
當(dāng)前網(wǎng)絡(luò)上有很多配置方案,但是更多都是使用七牛云作為網(wǎng)站圖床使用. 因?yàn)槠吲T茣?huì)提供新用戶每月10G上傳圖片的免費(fèi)空間,當(dāng)然你也可以選擇其他服務(wù)商提供的對象存儲(chǔ)服務(wù),但具體優(yōu)惠情況還要自己探究.
本篇文章主要記錄我自己寫的博客網(wǎng)站后臺(tái)使用mdeditor編輯器配合七牛云完成圖片上傳的主要操作!
一. 配置mdeditor
安裝配置
pip install django-mdeditor -i https://pypi.douban.com/simple
注冊為應(yīng)用
INSTALLED_APPS = [
...
'mdeditor',
]
在 settings 中添加媒體文件的路徑配置:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
注意:django3中
X_FRAME_OPTIONS默認(rèn)為 deny.如果你使用的是django3要在settings中添加X_FRAME_OPTIONS = 'SAMEORIGIN',否則會(huì)出現(xiàn)跨域問題,導(dǎo)致圖片上傳后無法預(yù)覽等問題!
添加擴(kuò)展url和媒體文件url
from django.conf.urls import include
from django.contrib import admin
from django.urls import path
urlpatterns = [
....
path('mdeditor/', include(('mdeditor.urls', 'mdeditor'), namespace='mdeditor')), # 配置編輯器路由
re_path(r'^media/(?P<path>.*)$', serve, {'document_root': MEDIA_ROOT}), #添加上傳文件路徑
....
修改models.py里需要使用編輯器渲染的字段
body = MDTextField(verbose_name='文章內(nèi)容')
遷移數(shù)據(jù)庫并注冊入admin中, 再次運(yùn)行程序即可使用markdown編輯器
測試使用編輯器上傳圖片,觀察圖片是否可正常查看與預(yù)覽,此處略
二. 注冊七牛云
注冊沒什么難度,只要按照要求即可順利完成注冊,七牛地址
記得實(shí)名認(rèn)證!
創(chuàng)建存儲(chǔ)空間
主要操作步驟:
進(jìn)入七牛選擇產(chǎn)品-->對象存儲(chǔ)-->空間管理-->新建空間-->配置存儲(chǔ)空間信息
-
選擇對象存儲(chǔ)
image.png -
新建空間
image.png -
配置空間信息
image.png
空間建議選擇公開,后面?zhèn)鲌D片訪問時(shí)不會(huì)報(bào)錯(cuò)!
使用七牛云SDK
要使用七牛云官方已給出完整的SDK文檔
參考文檔
安裝
pip install qiniu
新增settings關(guān)于七牛云的配置
Access_Key = '你的Access_Key '
Secret_Key = '你的Secret_Key'
QINIU_URL_DOMAIN = 'xxxx.com' # 首次注冊七牛云的用戶,官方會(huì)提供一個(gè)30天的測試域名使用
封裝七牛上傳圖片函數(shù)
在項(xiàng)目中創(chuàng)建utils目錄,并創(chuàng)建qiniu.py文件用于封裝函數(shù)
# -*- coding: utf-8 -*-
# flake8: noqa
import datetime
from qiniu import Auth, put_file, etag, put_data
import qiniu.config
#需要填寫你的 Access Key 和 Secret Key
from run.settings import Access_Key, Secret_Key, QINIU_URL_DOMAIN
access_key = Access_Key
secret_key = Secret_Key
qiniu_url_domain = QINIU_URL_DOMAIN
# 為了顯示圖片類型,傳入mdeditor源碼中類型參數(shù)
def storage(file_data, file_extension):
'''
上傳圖片到七牛
'''
#構(gòu)建鑒權(quán)對象
q = Auth(access_key, secret_key)
#要上傳的空間
bucket_name = 'wsmzao'
#上傳后保存的文件名(借鑒mdeditor源碼設(shè)置圖片名稱)
key = '%s.%s' % ('{0:%Y%m%d%H%M%S%f}'.format(datetime.datetime.now()),
file_extension)
#生成上傳 Token,可以指定過期時(shí)間等
token = q.upload_token(bucket_name, key, 3600)
#要上傳文件的本地路徑
# localfile = './sync/bbb.jpg'
ret, info = put_data(token, key, file_data)
# 最終返回顯示鏈接
if info.status_code == 200:
base_url = 'http://%s/%s' % (qiniu_url_domain, ret.get("key"))
return base_url
else:
raise Exception("上傳七牛失敗")
if __name__ == '__main__':
storage()
# 可通過本地圖片測試上傳
#if __name__ == '__main__':
# with open("本地上傳圖片.jpg", "rb") as f:
# file_data = f.read()
# storage(file_data)
先使用本地圖片測試一下是否可正常傳入七牛云,然后再做調(diào)整與修改
修改mdeditor上傳函數(shù)
觀察mdeditor源碼,對保存圖片處使用剛剛封裝的七牛函數(shù)做替換
# -*- coding:utf-8 -*-
import os
import datetime
from django.views import generic
from django.conf import settings
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from .configs import MDConfig
from django.views.decorators.clickjacking import xframe_options_exempt, xframe_options_sameorigin
from django.views.decorators.csrf import csrf_exempt
from utils.qiniu import storage
# TODO 此處獲取default配置,當(dāng)用戶設(shè)置了其他配置時(shí),此處無效,需要進(jìn)一步完善
MDEDITOR_CONFIGS = MDConfig('default')
class UploadView(generic.View):
""" upload image file """
@method_decorator(csrf_exempt)
def dispatch(self, *args, **kwargs):
return super(UploadView, self).dispatch(*args, **kwargs)
def post(self, request, *args, **kwargs):
upload_image = request.FILES.get("editormd-image-file", None)
# media_root = settings.MEDIA_ROOT
# image none check
if not upload_image:
return JsonResponse({
'success': 0,
'message': "未獲取到要上傳的圖片",
'url': ""
})
# image format check
file_name_list = upload_image.name.split('.')
# list.pop(-1)表示列表最后一個(gè)值
file_extension = file_name_list.pop(-1)
file_name = '.'.join(file_name_list)
if file_extension not in MDEDITOR_CONFIGS['upload_image_formats']:
return JsonResponse({
'success': 0,
'message': "上傳圖片格式錯(cuò)誤,允許上傳圖片格式為:%s" % ','.join(
MDEDITOR_CONFIGS['upload_image_formats']),
'url': ""
})
# save image
file_data = upload_image.read()
# 調(diào)用七牛云上傳
base_url = storage(file_data, file_extension)
return JsonResponse({'success': 1,
'message': "上傳成功!",
'url': base_url
})
最終效果展示:

如果你有自己的域名,建議直接改為自己的域名,這對于你應(yīng)該沒有什么難度!


