python笔记四 REST Framework 实现 restful api

2,965 阅读3分钟

python笔记一 django搭建服务器全栈开发
python笔记二 django自带后台管理系统、模版渲染以及使用mysql数据库
python笔记三 react + django 实现前后端分离
python笔记四 REST Framework 实现 restful api
python笔记五 django headers带jwt实现自动登录,密码加密存储

第一次看到REST Framework的时候一脸懵逼,这是啥。然后在网上查了一下,写了个demo,才知道这货有什么用。

上一篇做了前后端分离,django只负责接口,有一些地方不太友好。
一个是数据,从数据库里取出来的数据是字节数组,而我们需要的是对象,这就需要反序列化,虽然转化之后是对象,但是并不是想要的格式,还需要处理一下。
另一个就是路由,在urls里边写path,对应views的一个函数,看起来没什么问题,但是如果网站对数据操作比较多,比如说有很多个表,我要对每个表的数据进行删除操作,两种方式,一种是写不同的url,对应不同的删除函数,另一种是只有一个url,对应一个函数,传过来的参数带一个字段,根据这个字段判断应该删除哪个表里的数据,这两种方法都不太好。

REST Framework对这两块都做了比较好的处理,当然不只这一点,还有很多功能,暂时还没用到。

一、安装配置

先看一下初始化的项目结构,具体怎么新建项目如果不明白看前几篇笔记。

service
    ├── db.sqlite3
    ├── manage.py
    ├── server
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── apps.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    └── service
        ├── __init__.py
        ├── __pycache__
        │   ├── __init__.cpython-37.pyc
        │   ├── settings.cpython-37.pyc
        │   └── urls.cpython-37.pyc
        ├── settings.py
        ├── urls.py
        └── wsgi.py

修改models.py

from django.db import models
import uuid

# Create your models here.
class Person(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid1, editable=False, null=False) #如果没有这个字段  会有一个默认的自增id
    name = models.CharField(max_length = 6, null = False)
    age = models.IntegerField()
    time = models.DateTimeField(auto_now = True, null = False)

1、安装

 pip3 install djangorestframework

添加rest_frameworkINSTALLED_APPS

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

    'server',  
    'rest_framework'
]

server目录下新建一个serializers.py文件

from rest_framework import serializers
from server.models import Person

class PersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person
        fields = ('id', 'name', 'age', 'time')

server目录下新建一个urls.py作为路由

from server import views
from server.views import PersonViewSet

urlpatterns = [

]

修改service文件夹下的urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include

urlpatterns = [
    path('admin/', admin.site.urls),
    url('', include('server.urls'))
]

二、实现restful api

两种方式

1、APIView

views.py里新建一个Test的类

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response

# Create your views here.
class Test(APIView):
    def get(self, request):
        a = request.GET['a']
        res = {
            'success': True,
            'data': 'a'
        }
        return Response(res)

添加到server > urls.py

from server import views
from django.conf.urls import url

urlpatterns = [
    url('test/', views.Test.as_view())
]

postman测试一下

image.png
这样就实现了一个接口,如果需要其他类型的请求,只需要在Test类里新建post、put等方法,前端发送请求的url是一样的,不同的请求方式会自动匹配到不同的函数。

2、ViewSets

views.py修改如下

from django.shortcuts import render
from rest_framework.response import Response
from rest_framework import viewsets
from rest_framework.decorators import list_route
from server.serializers import PersonSerializer
from server.models import Person
import json
import uuid

# Create your views here.
class PersonViewSet(viewsets.ModelViewSet):

    @list_route(methods = ['post'])
    def new_person(self, request):
        data = json.loads(request.body)
        data['id'] = uuid.uuid1()
        Person.objects.create(**data)
        res = {
            'success': True,
            'data': data
        }
        return Response(res)

    @list_route(methods = ['get'])
    def all_person(self, request):
        data = PersonSerializer(Person.objects.all(), many = True).data
        res = {
            'success': True,
            'data': data
        }
        return Response(res)

server > urls.py修改如下

from django.conf.urls import url, include
from server.views import PersonViewSet
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'', PersonViewSet, base_name="person")

urlpatterns = [
    url('', include(router.urls))
]

postman测试一下 先用post添加一组数据

image.png
然后用get读取
image.png
注意数据格式,并没有做格式化,RESR Framework 已经做好了,可以对比一下之前的笔记看一下。

**mixins类的通用视图

把上边的PersonViewSet类修改如下

from rest_framework import viewsets
from server.serializers import PersonSerializer
from server.models import Person

class PersonViewSet(viewsets.ModelViewSet):
    queryset = Person.objects.all()
    serializer_class = PersonSerializer

保存,然后访问 http://127.0.0.1:8000,你没看错,就这几行代码。 先post一组数据

image.png
再get一个

image.png
什么都没做,只用了两行代码就搞定了,REST Framework已经全都做好了,routerget和自带的list绑定、postcreate绑定。