青魔法圣堂法术 Django REST framework (DRF) 框架(持续更新)
著名的Python高阶法术 DRF (Django REST framework)框架到底是做什么用的?
跳转到文章结尾 https://www.cnblogs.com/Asterism-2012/p/10046759.html
目录
【工具分享】Django开发,一条命令搭建DRF工程 自动建立完整项目工程-魏泯
从入门开始学习Django-rest-framework(简称DRF)- 魏泯 【完整源代码】
确保django2.0.6版本的环境搭建,环境详情见 青魔法使魏泯 Django圣堂法术和Python青魔法中收录。 确保mysql数据库的安装, 以及环境变量的配置。
确保自己有Python编程的能力,Django框架的基本知识,Mysql数据库的使用经验。
- 安装djangorestframework模块。
pip install djangorestframework
- 操作环境
操作系统: Windows10
Python版本: Python 3.6.5 |Anaconda, Inc.|
IDE: Pycharm
浏览器:谷歌浏览器
第一节 初探Django-rest-framework-魏泯
Django-rest_framework介绍
Django-rest_framework是干嘛的?一句话: 用来简化接口开发的,别问我什么是接口。好吧,它就是传输动态数据的。
这个名字这么长不太好念,所以就也被称为DRF框架,它是一个在django基础之上进行二次开发的一个前后端分离的web框架,它是严格遵守restful API规范的。
- 问题一:前后端分离与不分离的概念是什么?(这里不赘述。网上查查就有很多概念)。
- 问题二:什么是restful API 规范?
- 轻量级,一般通过http或者https协议,不需要额外的协议!常用的方法post,get,put,delete,(patch,options不常用)
- 面向资源,一目了然,具有意义(增删改查,都是动词,但是URI里要求是名词)
GET /zoos:列出所有动物园
POST /zoos:新建一个动物园
GET /zoos/ID:获取某个指定动物园的信息
PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息) - 一般通过json或者xml
- 版本(Versioning)应该将API的版本号放入URL。
http://www.example.com/app/1.0/foo
http://www.example.com/app/1.1/foo - 状态码(Status Codes)
200,404,500
DRF框架是用于简化数据优化与调整的,大大提高了开发速度。DRF做了很多重复性的工作。其中就包括数据序列化:
- 问题三: 什么是序列化呢,我不序列化行不行?
- 序列化(encoding):把python对象编码转换成Json字符串。
- 反序列化(decoding):把json格式字符串解码为python对象。
说白了就是对我们要的数据进行格式化编码,用于传输到需要它的地方。如果不了解编码,我推荐去张雪峰老师的Python3教程上查阅“编码”的内容,可以很好的帮助了解编码的由来与作用。
- 还有: 别问我什么是数据了,我不告诉你┭┮﹏┭┮。
- 问题怎么这么多...别想那么远啦
实战DRF(Django-rest-framework)-【完整源代码】!
我们以一个简单的项目作为例子,通过一步一步的学习项目的构建,来了解序列化器的使用。这不会耗费很多的时间。
在这个项目中,我们来简单了解API是如何提供数据的。
从现在开始,不要复制我的代码,自己一个字母一个字母的将我的代码写入你的Python中。确保它不会出错,并且观察它,主动寻找解决问题的办法。如果你是一个DRF的老手,并觉得我的讲解太过详细的话,这篇文章不适合你。
- 建立django项目
文件位置: [ 当前Console窗口命令行所在的位置 ]
方式一:通过命令行建立项目(两者选其一)
创建一个名为demo的示例项目,demo的英文词义就是例子的意思,以demo为项目仅仅用于学习相关语法。而不用于线上部署。
E:\Django-codes> django-admin startproject demo
方式二:通过Pycharm自带功能建立项目
File----New project然后通过配置窗口中的相关设置来利用Pycharm自动创建项目,用这种方法创建的项目,Pycharm会自动配置好应用和模板的初步相关设置。但是很多东西都需要手动去配。
- 创建应用
文件位置:[ 当前Console窗口命令行所在的位置 ]
方式一: 使用命令行手动创建则需要这样:创建一个名为User的应用。(两者任选其一)
E:\Django-codes\> cd demo
E:\Django-codes\demo> python manage.py startapp User
方式二:通过Pycharm自带功能建立应用
使用Pycharm来创建项目的方式能可以直接建立app,并且Pycharm会自动会将app加载到setting.py文件中。
- 配置项目
setting.py
文件位置: [ demo> setting.py
]
安装应用
INSTALLED_APPS = [
'''INSTALLED_APPS中系统默认的内容跟我们先简略掉,为了让大家能够更加专注清晰地看到我们自己自己手动添加了哪些东西'''
'User.apps.UserConfig', # 安装应用
'rest_framework', # 安装rest_framework
]
以Mysql数据库作为例子,所以在本例中我会配置mysql的交互信息。这些相关参数都是填自己的,这里不讲解mysql的交互参数,在注释中都有。这都是基础知识。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'drf_demo', # 数据库名称(这个要提前建立好)
'USER': 'root', # 服务器端管理员名称默认为root
'PASSWORD': '自己的密码', # 这里填写自己的密码
'HOST': 'localhost', # 或者127.0.0.1
'PORT': 3306,
}
}
本地化设置(语言与时间),是可选的。在本例中,设置或不设置都行,丝毫不影响学习进度与页面效果。这就是为了回忆下Django开发的日常。
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
模板设置也不需要,因为在这个小节中我们不需要用它。
- 配项目根级目录的
__init__.py
文件,装载mysql客户端。
文件位置: [ demo> __init__.py
]
大多数时候,如果不写这一步,我们无法进行模型迁移。如果有兴趣可以试试不进行这一步,了解一下会报什么样的异常。
import pymysql
pymysql.install_as_MySQLdb()
- 建立数据库
建立数据库是必须的。所以,我们打开在终端中操作:(以windows为例,快捷键Win+R 输入cmd 然后回车)
C:\>mysql -uroot -p
Enter password: *****
密码输入正确后是显示这样的提示:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1040
Server version: 5.7.19-log MySQL Community Server (GPL)
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
创建数据库drf_demo,指定字符集为utf-8,sql语句中“utf-8”写作“utf8”。
mysql>create databases drf_demo charset=utf8;
Query OK, 1 row affected (0.01 sec)
创建成功则会显示Query OK。
- 设计模型类
文件位置: [ demo> User> Models.py
]
模型类的字段按照我的示例代码来写,便于第二节的学习。
'''django已经为我们引入models'''
class User(models.Model): # 建立User表,包含几个字段
'''字段名称 = models.字段类型(字段参数)'''
nick_name = models.CharField(max_length=20, verbose_name='昵称')
add_time = models.DateField(auto_now_add=True, verbose_name='创建时间')
gender = models.BooleanField(default=True, verbose_name='性别')
image = models.ImageField(upload_to='media', verbose_name='图片', null=True)
mobile = models.CharField(max_length=11, verbose_name='手机号', null=True)
'''下面的元类和魔法方法可以不定义,丝毫不影响数据表的健全性能'''
class Meta: # 定义元类
db_table = 'users' # 定义将来迁移数据模型时,生成的表名
verbose_name_plural = '用户'
def __str__(self):
'''这里return什么都行,就是一个标识,写字符串也可以。魔法方法,str。为每一条记录返回对应昵称'''
return self.name
- 迁移数据库
第一步:生成迁移(文件)
E:\Django-codes\demo> python manage.py makemigrations
这条命令启动之后,Django框架会为我们生成一个文件,存放在项目根目录下的“migrations”文件夹中,名为“0001_initial.py”。
创建成功会显示这样的提示:
Migrations for 'User':
User\migrations\0001_initial.py
- Create model User
它用于为我们生成并且执行对应的sql语句,与数据库进行直接交互。
第二步:执行迁移
E:\Django-codes\demo> python manage.py migrate
成功会显示:
Performing system checks...
System check identified no issues (0 silenced).
You have 14 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
November 09, 2018 - 13:54:09
Django version 2.0.6, using settings 'demo10.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
(Py_Django2.0.6) E:\PyAsterism\DRF-codes\demo10>python manage.py makemigrations
Migrations for 'User':
User\migrations\0001_initial.py
- Create model User
(Py_Django2.0.6) E:\PyAsterism\DRF-codes\demo10>python manage.py migrate
Operations to perform:
Apply all migrations: User, admin, auth, contenttypes, sessions
Running migrations:
Applying User.0001_initial... OK
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying sessions.0001_initial... OK
这时候Django就在MySQL数据库中创建数据表了(在drf_demo库中)。
- 查询数据库
这一步是可选的,主要是看看它到底建立没建立数据表;
一、使用drf_demo数据库:
mysql> use drf_demo;
成功则显示:
Database changed
二、查看数据表:
mysql> show tables;
成功则显示:
+----------------------------+
| Tables_in_drf_demo10 |
+----------------------------+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
| users |
+----------------------------+
11 rows in set (0.00 sec)
我们已经看到了它建立了这么多表,接下来去建立序列化器吧。这个窗口先不要关。
- 设置序列化器
文件位置[ demo> User> serializers.py
]
设计序列化器要根据自己的需求进行设置,它可以理解为一种规则。
from rest_framework import serializers # 导入serializers
class Userserializers(serializers.Serializer):
nick_name = serializers.CharField(max_length=20, required=True) # 这里的字段类型属性并不和Models完全一直,要留心观察其中的区别
gender = serializers.BooleanField(default=0, required=False) # required 意为‘该字段必须填写’ 它的默认值是True
image = serializers.ImageField(required=False)
add_time = serializers.DateField(required=False)
mobile = serializers.CharField(max_length=11, required=False)
注意:这个文件名是我们手动创建的,而且serializers这个名字也不是规定,而是一种规范。
序列化器是可以脱离数据表模型单独存在的,它不依赖模型类的存在而存在,它的核心功能是格式化数据。也就是说它也可以处理我们自己定义的一些数据。
- 设置视图
文件位置[ demo> User> Views.py
]
from rest_framework.views import APIView # 导入APIView视图
from .models import UsersModels # 引入数据模型类
from rest_framework.response import Response # 导入drf框架提供的Response
from rest_framework import status # 状态码
'''定义视图'''
class UsersAPIViews(APIView): # 继承APIView
def get(self, request): # request是必填参数
users = UsersModels.objects.all() # 获取数据库中所有的数据
ser = UsersSerializers(instance=users, many=True) # many=True 表示序列化器接收多条数据
return Response(ser.data, status=status.HTTP_200_OK) # 返回序列化后的数据以及状态码
- 主路由定义
文件位置[ demo>urls.py
]
'''上面系统自己生成的内容我们先忽略掉,下面前两行的导入模块是系统自己定义的'''
from django.conf.urls import url, include # 导入url与include这两个包
urlpatterns = [
....
url('^', include('User.urls')),
]
- 子路由定义 遵循restful api规范协定,名词定义用复数形式 如zoo,则写成zoos
文件位置[ demo>User>urls.py
]
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^users/$',views.UsersAPIView.as_view())
]
- 运行项目
E:\Django-codes\demo> python manage.py runserver
成功会显示这样的提示:
Performing system checks...
System check identified no issues (0 silenced).
November 08, 2018 - 08:55:44
Django version 2.0.6, using settings 'demo30.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
- 打开谷歌浏览器
一、在地址栏访问http://127.0.0.1:8000/
,等待页面的显示。
是这样显示的:
吐槽下自己的网速。
二、在地址栏访问 http://127.0.0.1:8000/users/
,等待页面的展示。
可以在网页上看到很多信息,比如状态码,所使用的表名称等。在侧边还有一些功能按钮,但这些按钮目前没有什么用。先不用管它。
- 增加数据,然后刷新页面。
我们看到页面上的“[]”中什么都没有显示,那是因为我们的User表中还没有任何的数据。
一、切换到刚才打开的cmd中,操作MySQL查看表结构
mysql> desc users;
成功显示:
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| nick_name | varchar(20) | NO | | NULL | |
| gender | tinyint(1) | NO | | NULL | |
| image | varchar(100) | YES | | NULL | |
| add_time | date | YES | | NULL | |
| mobile | varchar(11) | NO | | NULL | |
+-----------+--------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)
二、插入数据
mysql> insert into drf_demo10.users
-> (id, nick_name, gender, image, add_time, mobile)
-> values
-> (1, "王司徒", 1, null, "2018-11-09", "13000000000");
成功则显示:
Query OK, 1 row affected (0.01 sec)
三、查看数据库
mysql> select * from drf_demo10.users;
成功会显示:
+----+-----------+--------+-------+------------+-------------+
| id | nick_name | gender | image | add_time | mobile |
+----+-----------+--------+-------+------------+-------------+
| 1 | 王司徒 | 1 | NULL | 2018-11-09 | 13000000000 |
+----+-----------+--------+-------+------------+-------------+
1 row in set (0.00 sec)
四、浏览器访问 http://127.0.0.1:8000/users/
,等待页面的展示。
- 第一小节结束
回顾一下,通过刚才的练习,我们制作了最基本的一个API接口网址。为前端提供数据支持。
在下面的小节里,一起学习搭建接下来的API的方法吧。
——向前走吧,往往最珍贵的东西都不容易在表层浮现的事物找到。