django mysql資料庫及圖片上傳介面詳解
前言
我們在django-rest-framework解析請求引數文章中完成了介面文件到引數解析,一個完整的流程中還缺少對資料庫的操作. 本篇內容為django連線資料庫,並編寫一個image表用來儲存圖片路徑,編寫圖片上傳介面和檢視資料庫中所有圖片路徑的介面.
前期準備
django操作圖片需要安裝一個三方庫叫做,Pillow
workon python35 pip install pillow pip install pymysql
Pillow這個庫可以對圖片進行操作,例如生成縮圖等等,非常強大.
pymysql是python3中用來連線資料庫的一個庫.
安裝mysql資料庫. 安裝MySQLWorkBench(作用和navicat一樣,使用其他軟體也可以)
選好點選apply 提交建立新庫.
django如何儲存圖片
一般圖片不存資料庫單獨儲存於某個路徑,開發過程中就存在專案的某個路徑下.
iOS開發中有個http 304問題. 就是請求圖片時,如果有快取直接取快取的圖片. 實際上蘋果早已幫我們處理好了. 實際開發中不需要針對http 304編寫任何程式碼.
關於http 304的問題
這一篇文章寫的非常詳細了.
現在我們進行服務端程式設計,服務端是如何生成etag,last-modify這些引數的呢?
這個問題涉及到服務端框架對靜態資源的管理方法.
在實際將專案部署到伺服器上時,我們對動態資源和靜態資源是分開管理的. 我使用nginx+uwsgi 部署,nginx 管理靜態資源,ETag 之類的,nginx 會自動生成,管理,不需要服務端程式設計師為此編寫什麼程式碼.....
圖片上傳介面,接收到圖片檔案,型別,大小校驗,將圖片儲存到靜態檔案目錄下,生成此圖片的url儲存到mysql資料庫.
編寫儲存圖片路徑和id的表.
修改models.py檔案.
from django.db import models import datetime class Image(models.Model): # url = models.TextField(null=True) image = models.ImageField(upload_to=str('image/{time}'.format(time=str(datetime.date.today().strftime("%Y%m/%d"))))) create_time = models.DateTimeField(auto_now_add=True,null=True) update_time = models.DateTimeField(auto_now=True,null=True) class Meta: pass
ImageField中的upload_to表示圖片上傳的具體路徑.
修改資料庫配置連線mysql
修改settings.py檔案中的DATABASES 到下面的樣式. name是剛剛建立mysql新庫的名稱. user password 是mysql使用者的使用者名稱和密碼. mysql埠號預設為3306
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql','NAME': 'test','USER': 'root','PASSWORD': '111111','HOST': '127.0.0.1','PORT': '3306',} }
記得刪除 migrations目錄下除了__init__.py 之外的所有檔案.
這些檔案記錄了對資料庫定義個整個修改流程. 切換資料庫後這個流程和新庫根本對不上號. 需要全部刪除.
修改與settings.py 同一目錄的__init__.py 檔案
新增兩行程式碼
import pymysql pymysql.install_as_MySQLdb()
cd到專案manage.py檔案的路徑下,執行
workon python35 python manage.py makemigrations python manage.py migrate
使用mysqlworkbench 連線3306開啟之前建立的庫可以看到表都已經被創建出來
編寫圖片上傳介面
from rest_framework import serializers class ImageUploadSerializer(serializers.Serializer): token = serializers.CharField(max_length=100) image = serializers.ImageField() from .models import * from django.views.decorators.csrf import csrf_exempt import time import hashlib class ImageUpload(APIView): ''' 圖片上傳介面 \n "http://127.0.0.1:8000/pages/uploadImage" (我簡單寫了個頁面做提交)\n ''' # coreapi_fields = (DocParam(name='token',description='token'),# DocParam(name='image',description='檔案',type='file'),) @csrf_exempt def post(self,request,*args,**kwargs): image = request.FILES['image'] data = get_parameter_dic(request) # 需要判斷檔案型別是否是圖片. serial = ImageUploadSerializer(data={"token": data["token"],"image": image}) if serial.is_valid(): print("校驗成功") else: return JsonError("引數校驗失敗") image = serial.validated_data.get("image") new_image = Image(image=image) imageName = str(new_image.image.name) location = str(imageName).find('.') extension = imageName[location:] name = imageName[:location] namestring = name+str(time.time()) md5 = hashlib.md5(namestring.encode('utf-8')).hexdigest() new_image.image.name = md5[:10] + extension new_image.save() return JsonResponse(data=new_image)
執行專案
呼叫上傳圖片介面,我用了postman測試介面
圖片儲存位置
圖片的完整訪問路徑為
http://localhost:8000/image/201710/20/d527b242d1.jpg
此時請求會失敗因為這個路徑不允許訪問,需要進行簡單配置
setting.py 檔案中新增
MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR,'media').replace('\\','/')
urls.py檔案中新增
from django.conf.urls import url,include from django.contrib import admin from rest_framework.schemas import get_schema_view from mytest.views import ReturnJson import mytest from mytest.views import SwaggerSchemaView from mytest.views import ImageUpload from django.views.static import serve from django.conf import settings urlpatterns = [ url(r'^admin/',admin.site.urls),url(r'^api-auth/',include('rest_framework.urls',namespace='rest_framework')),url(r'^docs/',SwaggerSchemaView.as_view(),name='apiDocs'),url(r'^api/getjson',ReturnJson.as_view()),url(r'^api/uploadimage',ImageUpload.as_view()),# url(r'^static/(?P<path>.*)$',serve,{'document_root': settings.STATIC_ROOT}),url(r'^media/(?P<path>.*)$',{'document_root': settings.MEDIA_ROOT}),]
這次圖片連結變為
http://localhost:8000/media/image/201710/20/d527b242d1.jpg
寫一個查詢所有圖片並返回json的介面
from .models import Image class GETAllImages(APIView): def get(self,**kwargs): imagesset=Image.objects.all() return JsonResponse(data=imagesset)
修改urls.py檔案新增此介面
from django.conf.urls import url,include from django.contrib import admin from rest_framework.schemas import get_schema_view from mytest.views import ReturnJson import mytest from mytest.views import SwaggerSchemaView from mytest.views import ImageUpload,GETAllImages from django.views.static import serve from django.conf import settings urlpatterns = [ url(r'^admin/',url(r'^api/getallimage',GETAllImages.as_view()),url(r'^static/(?P<path>.*)$',]
全部搞定
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。