1. 程式人生 > 資料庫 >django mysql資料庫及圖片上傳介面詳解

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>.*)$',]

全部搞定

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。