django-mysql数据库及图片上传接口

前言

之前的文章完成了接口文档到参数解析, 一个完整的流程中还缺少对数据库的操作. 本篇内容为django连接数据库, 并编写一个image表用来存储图片路径, 编写图片上传接口和查看数据库中所有图片路径的接口.

前期准备

django操作图片需要安装一个三方库叫做,Pillow

workon python35
pip install pillow
pip install pymysql

Pillow这个库可以对图片进行操作, 例如生成缩略图等等, 非常强大.
pymysql是python3中用来连接数据库的一个库.

安装mysql数据库. 安装MySQLWorkBench(作用和navicat一样,使用其他软件也可以)

django-mysql数据库及图片上传接口_第1张图片
mysql0.png

选好点击apply 提交创建新库.

django如何存储图片

一般图片不存数据库单独存储于某个路径, 开发过程中就存在项目的某个路径下.
iOS开发中有个http 304问题. 就是请求图片时, 如果有缓存直接取缓存的图片. 实际上苹果早已帮我们处理好了. 实际开发中不需要针对http 304编写任何代码.

关于http 304的问题
https://segmentfault.com/a/1190000004356632
这一篇文章写的非常详细了.

现在我们进行服务端编程, 服务端是如何生成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打开之前创建的库可以看到表都已经被创建出来

django-mysql数据库及图片上传接口_第2张图片
mysql1.png

编写图片上传接口

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)

运行项目

django-mysql数据库及图片上传接口_第3张图片
swagger0.png

调用上传图片接口, 我用了postman测试接口

django-mysql数据库及图片上传接口_第4张图片
postman0.png

图片存储位置

django-mysql数据库及图片上传接口_第5张图片
imagedir.png

图片的完整访问路径为

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.*)$', serve, {'document_root': settings.STATIC_ROOT}),
    url(r'^media/(?P.*)$', serve, {'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, 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.*)$', serve, {'document_root': settings.STATIC_ROOT}),
    url(r'^media/(?P.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
]

全部搞定

django-mysql数据库及图片上传接口_第6张图片
getimage.png

你可能感兴趣的:(django-mysql数据库及图片上传接口)