网站建设资讯

NEWS

网站建设资讯

RestFramework:一,认识RESTful

一、CBV的源码分析

成都创新互联专注为客户提供全方位的互联网综合服务,包含不限于网站制作、成都做网站、通河网络推广、微信小程序、通河网络营销、通河企业策划、通河品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;成都创新互联为所有大学生创业者提供通河建站搭建服务,24小时服务热线:18980820575,官方网址:www.cdcxhl.com

-Class Base View(基于类的视图)
    -Function Base View(基于函数的视图)

    -def as_view 类方法
    -def view:类方法内部

    闭包函数定义:内层函数包含对外部作用域的引用

    -python中一切皆对象:函数也是对象

    -hasattr(self, 'get')--判断self类中是不是有该(get)方法  
    -反射 setattr(self,get,get_all):相当于把get函数,变成了get_all
    -getattr(self, 'get'):拿到get函数的内存地址

Rest Framework:一,认识RESTful

# 执行:dispatch:谁的dispatch方法?写的cbv的那个c,视图中的那个视图类
# 我这个类如果没有写dispatch,会执行View中的dispatch方法
   return self.dispatch(request, *args, **kwargs)

与上方截图是同一地方代码。

下面作用:在路由选择之前(urls.py),是走哪个请求(例如:'get','post'等),是由dispatch来决定的。

Rest Framework:一,认识RESTful

-def dispatch(self, request, *args, **kwargs):
        # request.method 前台请求的方法,转成了小写
        # http_method_names View中定义的一个列表:是一堆请求方式
        if request.method.lower() in self.http_method_names:  #  http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
            # getattr的第三个参数是默认值:self.http_method_not_allowed
            # 拿到get方法的内存地址
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        #get(request,*args, **kwargs)
        return handler(request, *args, **kwargs)

    总结:*******请求来了--->as_view---->view---->dispatch--->分发到不同的函数,执行函数,拿到结果,然后返回

urls.py

# as_view(),是从View中继承过来的,用类来调用的,它是一个类的方法。

# 如果是get请求,会影响到类内部,执行get(或是post)方法

# View类内部函数的内存地址。(例如:get与post的函数重写)

url(r'^login/', views.Test.as_view()),

views.py

from django.views import View
class Test(View):
    def get(self,request,*args,**kwargs):
        print('get')
        return render(request,'login.html')
    def post(self,request): # 知道这里没传,所以没写,正常情况下要写上-> def post(self,request,*args,**kwargs)
        name=request.POST.get('name')
        pwd=request.POST.get('pwd')
        if name=='user' and pwd=='123':
            return HttpResponse('successful')
        else:
            return render(request,'login.html',{'error':'用户名密码错误'})

templates/login.html




    
    login



    

用户名:

    

密码:

    

{{ error }}

访问:http://127.0.0.1:8000/login/

登录中是整个页面刷新的,如果只是局部刷新的话,应该用的是ajax提交的表单

阅读源码:(pycharm)
 左侧工程栏--->设置图标-->点击--->show members(能看到py文件,类的方法)


二、resful规范(是什么)

    - 是一个规范
    - 面向资源编程:把网络中所有东西,想象成资源

    -规范:

        -10条规范

               1、-API与用户的通信协议,总是使用HTTPs协议:https比http安全       

               2、-域名

                        https://api.example.com  尽量将API部署在专用域名(会存在跨域问题)
                        https://example.org/api/  API很简单
                        例如写一个查询所有图书的api接口:

                        https://api.example.com/books

                        https://127.0.0.1/api/books

               3、版本:每个接口都应该有版本

                   URL

                        如:https://api.example.com/v1/   

                                https://127.0.0.1/api/v2/books(推荐用这种)
                                请求头 跨域时,引发发送多次请求
               4、路径,视网络上任何东西都是资源,均使用名词表示(可复数)
                                https://api.example.com/v1/books
                                https://api.example.com/v1/animals
                                https://api.example.com/v1/employees
            不能这么写:
                -获取所有图书:https://127.0.0.1/api/get_all_books
                -新增一本书:https://127.0.0.1/api/add_book
            同一都用这个:
            https://api.example.com/v1/books

               5、method

                   GET      :从服务器取出资源(一项或多项)
                   POST    :在服务器新建一个资源
                   PUT      :在服务器更新资源(客户端提供改变后的完整资源)
                   PATCH  :在服务器更新资源(客户端提供改变的属性)
                   DELETE :从服务器删除资源

               6、过滤,通过在url上传参的形式传递搜索条件

      • https://api.example.com/v1/zoos?limit=10:指定返回记录的数量

      • https://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置

      • https://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数

      • https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序

      • https://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件

                 7、状态码

                    请求回去,需要有状态码
                    自定义状态码
                    status: 100表示成功
                                101表示用户名密码错误
                                102我也不知道什么错误

               8、错误处理,应返回错误信息,error当做key。

                            -{status:100,error:'错误信息写上'}

                 9、返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范。

                                GET /books:返回资源对象的列表(数组)
                                GET /books/1:返回单个资源对象
                                POST /books:返回新生成的资源对象    -新增,传数据,一旦新增完成,把新的资源对象返回
                                PUT /books/1:返回完整的资源对象
                                PATCH /books/1:返回完整的资源对象
                                DELETE /books/1:返回一个空文档

                 10、Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。

                 {
                    status:100
                    msg:成功
                    url:127.0.0.1/books/1
                }
            核心:返回结果中提供链接

  1、django写resful规范的接口与postman软件:模拟发请求的软件

    -格式化json格式数据
        -https://www.json.cn/
    put请求,django不会帮我解析body内的数据,需要自己处理

models.py

class Book(models.Model):
    name=models.CharField(max_length=32)
    price=models.CharField(max_length=32)

数据库迁移

python3 manage.py makemigrations

python3 manage.py migrate

urls.py

url(r'^books/$', views.Books.as_view()),
url(r'^books/(?P\d+)', views.Books.as_view()),

views.py

from django.http import JsonResponse
from django.views import View
from app01 import models
class Books(View):
    def get(self, request):
        response = {'status': 100, 'data': None}
        books = models.Book.objects.all()
        lst = [{'name': book.name, 'price': book.price} for book in books]
        response['data'] = lst
        return JsonResponse(response, safe=False)

    def put(self, request, pk):
        import json
        data = json.loads(str(request.body, encoding='utf-8'))
        name = data.get('name')
        price = data.get('price')
        ret = models.Book.objects.filter(pk=pk).update(name=name, price=price)
        return JsonResponse({'status': 100, 'msg': '修改成功'}

login.html




    
    login



    

用户名:

    

密码:

    

{{ error }}

通过postman的get请求查看数据

Rest Framework:一,认识RESTful

通过postman的put请求修改数据库中的数据

例如:

Rest Framework:一,认识RESTful

查看数据库对应已修改人的数据

Rest Framework:一,认识RESTful


2、drf(django rest framework)框架(django的app)

安装:djangorestframework
    -它是一个app,要在咱的项目中用,需要配置以下配置

    在settings.py文件中的 INSTALLED_APPS字段中添加:

        'rest_framework',

    -只是快速的构建resful规范的接口
    -csrf_exempt:局部禁用csrf(csrf是可以局部使用,局部禁用)
    -以后再执行的dispatch方法是APIView的dispatch方法
    -getattr和setattr

urls.py

url(r'^books/$', views.Books.as_view()),
url(r'^books/(?P\d+)', views.Books.as_view()),

views.py

from rest_framework.views import APIView
class Books(APIView):
    # 现在这个request对象,已经不是原来django中的request对象了,它是rest_framework.request下的Request
    def put(self,request,pk):
        # django.core.handlers.wsgi.WSGIRequest----原来的djagno中的request的类
        # 现在的request已经成了:rest_framework.request.Request
        # print(request.PUT)
        # 以后再取数据,直接从request.data中取
        print(request.data)
        # 前端传过来的编码格式:json格式:{'name': '二狗子', 'price': '9879797987'}
        # 前端传过来的编码格式: urlencoded格式:
        # request.data不同编码格式过来,它可能是不同类的对象,但是用法是一样的
        # 原来的request是:request._request
        print(type(request._request))
        print(request._request.GET)
        # 也能取出来(method,GET,POST,BODY)
        print(request.GET)
        return JsonResponse({'status':100,'msg':'修改成功'})

models.py(与之前上面的内容一样)

使用postman 测试发送数据

Rest Framework:一,认识RESTful

   -重点掌握这三点:
        -request.data 是个方法,包装成了属性,前台传过来body体中数据的数据,放在里面
        -request.query_params  这个是原来GET中的数据
        -request把原来的request包装进去了

3、序列化

-1 自己写for循环来处理(麻烦)
-2 django提供的序列化组件(不可控)
        from django.core import serializers
        ret=serializers.serialize('json','queryset对象')
        ret就是序列化之后的字符串了,不需要再序列化了

使用django自带的序列化组件。

urls.py与models.py之前都一样,主要是views.py

from rest_framework.views import APIView
from django.core import serializers # django 序列化组件
class Books(APIView):
    def get(self,request):
        response={'status':100,'date':None}
        book=models.Book.objects.all()
    # 先构造出所有书籍的字典的列表
    # 用django提供的序列化组件
        ret=serializers.serialize('json',book)
        print(type(ret),ret)   #是我序列化完的值
    # 返回数据是json格式数据
        response['date']=ret
        return HttpResponse(ret)

使用postman查看结果,点击下面json按钮,从二进制转换成了json格式。

Rest Framework:一,认识RESTful

-3 drf给咱提供的序列化组件
         -1 先导入
            from rest_framework.serializers import Serializer
            from rest_framework import serializers
         -2 写一个类,继承Serializer
         -3 在类内部写属性:
            name=serializers.CharField()
          -4 使用:
            -先生成对象,需要传参数 instance:要序列化的对象(可能是queryset,也可能是单个对象)    
            many:如果是queryset---True,,如果是单个对象--False
         -5 对象.data --->是一个字典

urls.py与models.py与上面依然一样不变

views.py

from rest_framework.serializers import Serializer
from rest_framework import serializers
class Book_Serializer(Serializer):
    name=serializers.CharField() # 如果只需要看一个对像,那就只写一个就好
    price=serializers.CharField() # 如果 models.py 里面的是其他类型,不是str类型,那么这里也是可以接收的,只是又转为了str 类型
class Books(APIView):   
    def get(self,request):
        books=models.Book.objects.all()
        # 第三步,实例化产生对象
        # instance = books要序列化的queryset对象, many = True, 表示序列化多条
        ser=Book_Serializer(instance=books,many=True)
        # 可以不按关键字传,不写的话,便是按位置传参
        # ser=Book_Serializer(books,many=True)
        # ser.data 拿到的是序列化之后的字典,字典里可能套了列表,所以safe=False
        return JsonResponse(ser.data,safe=False)

使用postman 来查结果

Rest Framework:一,认识RESTful




网站栏目:RestFramework:一,认识RESTful
标题路径:http://njwzjz.com/article/gejocj.html