python實現本地圖片上傳到服務區
本地圖片上傳到服務器,其本質上來講,就是讀取本地圖片,復制到服務器,並返回服務器url
前端代碼,用的form表單提交,form表單中包含兩個文件選擇表單元素,選擇文件,點擊提交按鈕,提交form表單
服務端代碼如下:
def get_path_format_vars():
return {
"year":datetime.now().strftime("%Y"),
"month":datetime.now().strftime("%m"),
"day":datetime.now().strftime("%D"),
"date":datetime.now().strftime("%Y%m%D"),
"time":datetime.now().strftime("%H%M%S"),
"datetime":datetime.now().strftime("%Y%m%D%H%M%S"),
"rnd":random.randrange(100,999),
}
def GetOutputFileInfo(request, path_format, path_format_vars):
# 將保存的文件路徑和配置的靜態資源連接起來
outputPath = os.path.join(MEDIA_ROOT, path_format) # 這裏MEDIA_ROOT是在settings文件中配置的靜態資源路徑 MEDIA_ROOT = os.path.join(BASE_DIR, "media")
# 拼接文件名
outputFile = "%(basename)s_%(datetime)s_%(rnd)s.%(extname)s"%path_format_vars
outputFile = outputFile.replace("/","_")
# 將文件夾路徑和文件名拼接起來,生成帶完整路徑的文件路徑,用於返回給前端
outputPathFormat = os.path.join(path_format, outputFile)
# 文件路徑是否存在,如果不存在則創建一個
if not os.path.exists(outputPath):
os.makedirs(outputPath)
outputPath = outputPath.replace("/","\\")
outputPathFormat = outputPathFormat.replace("/","\\")
return(outputPathFormat, outputPath, outputFile)
def UploadFileToServer(request, filePath, file):
try:
# 以二進制格式寫入文件
f = open(filePath, "wb")
for chunk in file.chunks():
f.write(chunk)
except Exception as e:
f.close()
return u"寫入文件錯誤{}".format(e.message)
finally:
f.close()
return "success"
def UploadFile(request):
if not request.method == "POST":
return JsonResponse({"error":u"不支持此種請求"}, safe=False)
/** 這裏涉及到一個問題,就是多圖上傳獲取圖片,一直以來我們都是直接使用get來獲取但是如果是多圖,你會發現get拿到的永遠只有一個,經過debug調試我們可以看到,request.FILES是一個MultiValueDict類型,這種字典類型是特殊定義的,要取得list,需要用getlist方法
**/
files = request.FILES.getlist("upfile")
if len(files) == 0:
return JsonResponse({"error":u"請至少選擇一個文件"}, safe=False)
returnInfors = {} # 定義一個字典用來承載返回值
returnInfos["data"] = []
for file in files:
filename = file.name
fileSize = file.size
# 獲取不包括後綴的文件名和文件後綴
upload_origin_name, upload_origin_ext = os.path.splitext(filename)
# 自定義允許上傳的文件類型
allType = [".png", ".jpg", ".jpeg", ".gif", ".bmp"]
# 判斷文件上傳類型
if not upload_origin_ext in allType:
return JsonResponse({"error":u"服務器不允許上傳%s類型的文件"%upload_origin_ext}, safe = False)
# 判斷上傳文件的大小
maxSize = 10485760 # 自定義上傳文件大小限制10M
if fileSize > maxSize:
return JsonResponse({"error":u"文件大小不能超過%s"}%maxSize)
# 校驗做完了,開始正式上傳文件
path_format_var = get_path_format_vars() # 獲取時間相關參數,用於拼接文件名
path_format_var.update({
"basename":upload_origin_name,
"extname":upload_origin_ext[1:],
"filename":filename
})
# 取得文件輸出的路徑
outputPathFormat = "forum/images"
outputFormat, outputPath, outputFile = GetOutputFileInfo(request, outputPathFormat , path_format_vars)
# 開始寫入文件
state = UploadFileToServer(request, outputPath, outputFile)
# 寫完,將結果返回給前端
mediaurl = urljoin(MEDIA_URL, outputFormat) # MEDIA_URL 也是settings文件中配置的靜態資源路徑 MEDIA_URL = ‘/media/‘
# 將絕對路徑返回給前端
abs_url = request.build_absolute_uri(mediaurl)
return_info = {
"url":abs_url,
"original":upload_origin_name,
"type":upload_origin_ext,
"size":fileSize,
"state":state
}
returnInfos["data"].append(return_info)
return JsonResponse(returnInfos)
def GetFileUpload(request):
return UploadFile(request)
python實現本地圖片上傳到服務區