前言
之前的文章完成了接口文檔到參數(shù)解析, 一個完整的流程中還缺少對數(shù)據(jù)庫的操作. 本篇內(nèi)容為django連接數(shù)據(jù)庫, 并編寫一個image表用來存儲圖片路徑, 編寫圖片上傳接口和查看數(shù)據(jù)庫中所有圖片路徑的接口.
前期準(zhǔn)備
django操作圖片需要安裝一個三方庫叫做,Pillow
workon python35
pip install pillow
pip install pymysql
Pillow這個庫可以對圖片進(jìn)行操作, 例如生成縮略圖等等, 非常強(qiáng)大.
pymysql是python3中用來連接數(shù)據(jù)庫的一個庫.
安裝mysql數(shù)據(jù)庫. 安裝MySQLWorkBench(作用和navicat一樣,使用其他軟件也可以)
選好點(diǎn)擊apply 提交創(chuàng)建新庫.
django如何存儲圖片
一般圖片不存數(shù)據(jù)庫單獨(dú)存儲于某個路徑, 開發(fā)過程中就存在項(xiàng)目的某個路徑下.
iOS開發(fā)中有個http 304問題. 就是請求圖片時, 如果有緩存直接取緩存的圖片. 實(shí)際上蘋果早已幫我們處理好了. 實(shí)際開發(fā)中不需要針對http 304編寫任何代碼.
關(guān)于http 304的問題
https://segmentfault.com/a/1190000004356632
這一篇文章寫的非常詳細(xì)了.
現(xiàn)在我們進(jìn)行服務(wù)端編程, 服務(wù)端是如何生成etag, last-modify這些參數(shù)的呢?
這個問題涉及到服務(wù)端框架對靜態(tài)資源的管理方法.
在實(shí)際將項(xiàng)目部署到服務(wù)器上時, 我們對動態(tài)資源和靜態(tài)資源是分開管理的. 我使用nginx+uwsgi 部署, nginx 管理靜態(tài)資源, ETag 之類的, nginx 會自動生成,管理, 不需要服務(wù)端程序員為此編寫什么代碼.....
圖片上傳接口, 接收到圖片文件, 類型, 大小校驗(yàn), 將圖片保存到靜態(tài)文件目錄下, 生成此圖片的url存儲到mysql數(shù)據(jù)庫.
編寫存儲圖片路徑和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表示圖片上傳的具體路徑.
修改數(shù)據(jù)庫配置連接mysql
修改settings.py文件中的DATABASES 到下面的樣式. name是剛剛創(chuàng)建mysql新庫的名稱. user password 是mysql用戶的用戶名和密碼. mysql端口號默認(rèn)為3306
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test',
'USER': 'root',
'PASSWORD': '111111',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
記得刪除 migrations目錄下除了__init__.py
之外的所有文件.
這些文件記錄了對數(shù)據(jù)庫定義個整個修改流程. 切換數(shù)據(jù)庫后這個流程和新庫根本對不上號. 需要全部刪除.
修改與settings.py 同一目錄的__init__.py
文件
添加兩行代碼
import pymysql
pymysql.install_as_MySQLdb()
cd到項(xiàng)目manage.py文件的路徑下,運(yùn)行
workon python35
python manage.py makemigrations
python manage.py migrate
使用mysqlworkbench 連接3306打開之前創(chuàng)建的庫可以看到表都已經(jīng)被創(chuàng)建出來
編寫圖片上傳接口
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("校驗(yàn)成功")
else:
return JsonError("參數(shù)校驗(yàn)失敗")
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)
運(yùn)行項(xiàng)目
調(diào)用上傳圖片接口, 我用了postman測試接口
圖片存儲位置
圖片的完整訪問路徑為
http://localhost:8000/image/201710/20/d527b242d1.jpg
此時請求會失敗因?yàn)檫@個路徑不允許訪問, 需要進(jìn)行簡單配置
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>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
]
這次圖片鏈接變?yōu)?/p>
http://localhost:8000/media/image/201710/20/d527b242d1.jpg
寫一個查詢所有圖片并返回json的接口
from .models import Image
class GETAllImages(APIView):
def get(self, request, *args, **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/', 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'^api/getallimage', GETAllImages.as_view()),
url(r'^static/(?P<path>.*)$', serve, {'document_root': settings.STATIC_ROOT}),
url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
]
全部搞定