Restframework从入门到精通(一):Restframework之入门

2,686 阅读6分钟

官方文档(英文): www.django-rest-framework.org/

官方文档(翻译): www.sinodocs.cn/

官网文档(未翻译全)(推荐): q1mi.github.io/Django-REST…

参考文档: www.cnblogs.com/chenxuming/…

restful系列博客是在学习51cto的课程和在观看完官方文章之后的学习总结,自己重新做了一个案例来说明

个人博客:www.ly-blog.top/

Django Restframework是什么

Django RestframeworkDjango中可以 帮助我们快速的开发符合RESTful规范的接口的框架 ,RESTful是如今开发基本都会采用的规范

Restful规范

  • GET(SELECT):查询; 从服务器取出资源(一项或多项)。
  • POST(CREATE):新增; 在服务器新建一个资源。
  • PUT(UPDATE):覆盖,全部更新 ; 在服务器更新资源(客户端提供改变后的完整资源)。
  • PATCH(UPDATE):更新; 在服务器更新资源(客户端提供改变的属性)。
  • DELETE(DELETE):删除; 从服务器删除资源。
  • HEAD:获取资源的元数据。
  • OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。

Restframework作用

  • 路由

    • 可以通过as_view传参数,根据请求方式的不同执行响应的方法

    • 可以在url中设置一个结尾类似于.json的数据形式

  • 视图

    • 帮助开发者提供了一些类,并在类提供了很多的方法供我们使用
  • 版本控制

    • 在url中设置version参数,用户请求传入参数时,在request.version中获取版本,根据版本的不同做不同的处理
  • 认证

    • 写一个类并注册到认证类,在类的authticate方法中编写认证逻辑
      • 认证成功(user,auth)
      • rase AuthticateFaild(..)
      • None 继续
  • 权限

    • 写一个类并注册的权限类,在类的has_permission方法中写权限逻辑
  • 频率限制

    • 写一个类并注册的权限类,在类的allow_requset/wait 方法中写权限逻辑
      • 匿名
      • 用户
      • 返回为True或者FalseFalse就要执行wait方法
  • 解析器

    • 根据ContentType请求头,选择不同的解析器对请求体中的数据进行解析.
      • Content-Type : url-formedo
      • Content-Type :application/json
  • 分页

  • 序列化

    • queryset序列化以及对请求数据格式校验
  • 渲染器

    • 根据url中传入的后缀,决定在数据如何渲染到页面上

.......简单的总结就是,Django Restframework可以帮助你前后端分离开发,后台人员通过Restframework来开发API接口,前端人员写前端的页面(不论是PC还是移动端),到时候整合直接使用后端人员的接口就可以完成整个项目的开发

接下来我从把model的数据转换为json格式来引入Restframework的概念

model数据转换为json形式

在开始演示之前,要先配置好Django的基本配置:编写好model、setting配置、从model插入数据、view视图配置等操作,这里我一一演示一遍

演示前配置

先创建一个空文件夹,然后创建项目,如我下图所示

创建项目

然后使用pycharm打开项目,配置好数据库、插入Book(我拿来演示的app)到INSTALLED_APPS,以下是我的配置

setting.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'Book',
    'rest_framework',
]

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAdminUser',
    ],
    'PAGE_SIZE': 10
}
......

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'restful_demo',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}

根目录__init__文件

在我的restful_test(项目根目录)文件夹里面的的__init__.py文件,因为是python3版本, 所以要配置一下mysql

import pymysql
pymysql.install_as_MySQLdb()

创建model模型字段

在我创建的Book文件夹里面的model.py添加我要演示的字段

class Publish(models.Model):
    name=models.CharField(max_length=20,verbose_name="出版社名称",unique=True)
    address=models.CharField(max_length=128,verbose_name="地址")

    def __str__(self):
        return self.name

    class Meta:
        verbose_name="出版社"
        verbose_name_plural=verbose_name

然后对生成迁移文件和写入数据库

python manage.py makemigrations->python manage.py migrate

创建管理员为model添加数据

python manage.py createsuperuser创建好管理员的用户名和密码

然后在admin.py里面注册Book

from django.contrib import admin
from .models import Publish
# Register your models here.
admin.site.register(Publish)

这里我添加好了三条数据

Book数据

以上你要用Django shell添加也行

到这里演示前的准备都已经配置好了,接下来的都是配置view视图方法

方法一:使用字典的方式转换为json

from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic.base import View
from .models import Publish
import json
# Create your views here.

class Publish_list(View):
    def get(self,request):
        queryset=Publish.objects.all()
        data=[]
        for i in queryset:
            p_tmp={
                "name":i.name,
                "address":i.address
            }
            data.append(p_tmp)
        return HttpResponse(json.dumps(data),content_type="application/json")

    def post(self,request):
        pass

然后配置一下路由

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^publish/',Publish_list.as_view())
]

访问 http://127.0.0.1:8000/publish/

可以看到model的数据已经转换为json格式了

方法二:使用Django自带的model_to_dict方法

方法二其实是对方法一进行优化,Django默认自带了一个model_to_dict方法,可以帮助我们把model转换为一个字典

from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic.base import View
from .models import Publish
from django.forms.models import model_to_dict
import json
# Create your views here.

class Publish_list(View):
    def get(self,request):
        queryset=Publish.objects.all()
        data=[]
        for i in queryset:
            data.append(model_to_dict(i))
        return HttpResponse(json.dumps(data),content_type="application/json")

    def post(self):
        pass

方法二得出的结果还是一毛一样的

方法三:使用Django自带的序列化转换成json

from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic.base import View
from .models import Publish
from django.core import serializers
# Create your views here.

class Publish_list(View):
    def get(self,request):
        queryset=Publish.objects.all()
        data=serializers.serialize("json",queryset)

        return HttpResponse(data,content_type="application/json")
    def post(self):
        pass

总结

这个跟方法一和方法二的结果多了一个modelpk字段,但是方法三比其他两个方法更为简洁,更少的代码也更容易理解

如果单单只要提供信息的话使用方法三是完全足够的,从model读取信息转换为json格式方法三完全可以胜任。开发不仅仅只是把model转换为API,还要把API转换成model里面的数据

Restframework的使用

初识:自定义序列化的类

Restframework的用法是跟Djangoform表单的用法很相似

要先在创建一个serializers文件,这个文件里面存储序列化的字段

serializers .py

from rest_framework import serializers


class Publishserializer(serializers.Serializer):
    id=serializers.IntegerField(read_only=True)
    name= serializers.CharField(max_length=32)
    address=serializers.CharField(max_length=128)

以上字段已经完成了字段的序列化,在前面说的跟form表单验证的方法一样,也有个验证的方法,如果直接把字段序列化进去就会造成不安全的问题,如翻译文档所示:

翻译文档

所以我们要重写一个createupdate方法

serializers .py

from rest_framework import serializers
from .models import Publish


class Publishserializer(serializers.Serializer):
    id=serializers.IntegerField(read_only=True)
    name= serializers.CharField(max_length=32)
    address=serializers.CharField(max_length=128)

    def create(self, validated_data):
        #这里不用管validated_data是什么,只需要按照官网的方法所示,返回**validated_data就可以保证序列化的字段经过验证
        return Publish.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.name=validated_data.get("name",instance.name)
        instance.address=validated_data.get("address",instance.address)
        instance.save()
        return instance

然后我们使用Django shell测试一下

其中的is_vaild方法都跟form表单使用方法一样,然后再刷新网页看看数据

如图所示,就增加了我刚刚写的数据

使用:在view里面添加序列化方法

views.py

from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic.base import View
from .models import Publish
from django.core import serializers
from .serializers import Publishserializer
import json
# Create your views here.

class Publish_list(View):
    def get(self,request):
        queryset=Publish.objects.all()
        serializer=Publishserializer(queryset,many=True)    #many=True就是多个对象,要去遍历出来
        return HttpResponse(json.dumps(serializer.data),content_type="application/json")


    def post(self):
        pass

优化:继承model的字段

form一样,form可以继承model的字段,serializers 当然也可以,已经在model里面创建的字段,当然没有必要重新写一遍了,所以现在要改写一下serializers .py的代码

from rest_framework import serializers
from .models import Publish


class Publishserializer(serializers.ModelSerializer):
    class Meta:
        model=Publish
        fields=(
            "id",
            "name",
            "address"
        )

    def create(self, validated_data):
        #这里不用管validated_data是什么,只需要按照官网的方法所示,返回**validated_data就可以保证序列化的字段经过验证
        return Publish.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.name=validated_data.get("name",instance.name)
        instance.address=validated_data.get("address",instance.address)
        instance.save()
        return instance

其余配置不变,输入配置好的路由地址 http://127.0.0.1:8000/publish/ ,依然可以访问到同样的数据