前言
我们在 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>.*)$', 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<path>.*)$', serve, {'document_root': settings.STATIC_ROOT}),
- url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
- ]
全部搞定

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。