作为一个修电脑的老家伙,有的时候要开发一个啥系统的,就需要搞定后台,后台老板要搞定,才有底气。
一般我们搞定接口,都是用restful API. rest 指的是一组架构约束条件和原则,提供了一个新的架构设计思路,满足这些约束条件和原则的应用程序或设计就是 RESTful
在REST规则中,有两个基础概念:对象、行为 对象就是我们要操作的对象,例如添加用户的操作,那么对象就是user 行为有4种常用的:查看、创建、编辑、删除
rest的提出者很巧妙的利用http现有方法来对应这4种行为: GET - 查看 POST - 创建 PUT - 编辑 DELETE - 删除
今天要讲的是rest_framework框架,它是基于Django的,帮助我们快速开发符合RESTful规范的接口框架。
我们先来说说序列化器这个东西。在rest_framework中,序列化器是一个位于客户端和后台之间的中间层。这个中间层一个最基本的作用就是接受前端JSON字符串转化为后台python可以识别的对象;从后台获取python对象然后转化为给前端的JSON格式字符串。当然如果它仅仅是这个作用的话那用json.dumps和json.loads差不多了。一个亮点在于序列化器可以定义一些字段,让进出的数据可以“一个萝卜一个坑”地填入序列化器,从而就可以方便地进行格式转化,顺便还可以做做数据校验这种工作。序列化器的另一个方便之处在于它可以和django的模型层进行互动,从而大幅度减少了编码量。下面我们来看看具体的序列化器
序列化器的类在rest_framework.serializers中,最基本的一个序列化器类是Serializer。
我们通过继承Serializer类定义自己的序列化器类。通常在类中需要指出本序列化器所有需要进行处理的字段名和字段类型,看起来有点像在定义一个Model或者一个Form。
OK, 开战吧。 先准备环境,安装django和djangorestframework
pip install django
pip install djangorestframework
建一个项目:
django-admin startproject xxx
cd xxx
python manage.py startapp yyy
项目建好后,改配置:
INSTALLED_APPS = [
...
'bb',
'rest_framework'
]
文件末尾增加如下REST_FRAMWORK配置, 以使Api权限生效
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly',
]
}
安装好mysql后,就可以:
mysql -u root -p
show databases;
为Django项目创建数据库
create database rouboinfo default charset utf8 collate utf8_general_ci;
项目里面数据库的信息也要改 默认是:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
改成:
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'rouboinfo',
'USER': 'root',
'PASSWORD': 'root',
'HOST': '127.0.0.1',
'PORT': '3306',
}
初始化数据库
python manage.py makemigrations
python manage.py migrate
定义数据库表。 这里我们只演示一个记录设备启动次数的api接口所需的基本字段。
from django.db import models
class DeviceReport(models.Model):
"""
收集设备相关的统计数据
report_id
自增id作为主键
report_type
上报类型,比如启动上报:open
report_time
上报时间戳
device_id
可以描述设备的id
ip_address
公网ip地址
"""
report_id = models.IntegerField(primary_key=True)
report_type = models.CharField(max_length=100)
report_time = models.DateTimeField(auto_now_add=True)
device_id = models.CharField(max_length=200)
ip_address = models.CharField(max_length=50)
在每次修改model之后,都需要进行迁移和生效动作,毕竟我们修改了数据库结构了。
python manage.py makemigrations
python manage.py migrate
执行成功后,会生成rouboapi_devicereport的表。 然后做接口: 实现序列化器 我们使用Django REST framework 提供的序列化器简化代码。
在项里面建一个api文件夹 建立Serializers.py文件
from rest_framework import serializers
from ..models import DeviceReport
#class DeviceReportSerializer(serializers.HyperlinkedModelSerializer):
"""
序列化上报接口数据
#class Meta:
# model = DeviceReport
# fields = ('report_id', 'report_type', 'report_time', 'device_id', 'ip_address')
class DeviceReportSerializer(serializers.ModelSerializer):
class Meta:
model = DeviceReport # 要序列化的模型
fields = '__all__' # 要序列化的字段
建立views.py
from rest_framework import generics
from .serializers import DeviceReportSerializer
from ..models import DeviceReport
class DeviceReportlist(generics.ListCreateAPIView):
queryset = DeviceReport.objects.all()
serializer_class = DeviceReportSerializer
class DeviceReportDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = DeviceReport.objects.all()
serializer_class = DeviceReportSerializer
建立url文件
from django.urls import path
from . import views
app_name = 'bb' # 指定命名空间
urlpatterns = [
path('report/', views.DeviceReportlist.as_view(), name='report_list'),
path('report/<pk>/', views.DeviceReportDetail.as_view(), name='report_list_detail'),
]
然后配置项目路由:
from django.contrib import admin
from django.urls import path, include
from rest_framework.documentation import include_docs_urls
urlpatterns = [
path('admin/', admin.site.urls),
path('api/bb/', include('bb.api.urls', namespace='bb')),
就可以运行起来了:
python manage.py runserver
浏览器中输入:http://localhost:8000/api/bb/report/
建立一个用户登陆,就可以操作了
python manage.py createsuperuser
不建立一个用户,是无权限操作的。 登陆后就可以看到操作按钮了
查询下数据库,就有结果了:
然后加上文档:
from django.contrib import admin
from django.urls import path, include
from rest_framework.documentation import include_docs_urls
urlpatterns = [
path('admin/', admin.site.urls),
path('api/bb/', include('bb.api.urls', namespace='bb')),
path('docs/', include_docs_urls(title='文档')),
]
http://localhost:8000/docs/