DRF--day1

DRF–day1

1. 前置概念

前后端分离

  1. 后端为前端项目返回所需的数据,不再进行页面的渲染,不再控制前端样式的效果
  2. 无论前端项目app|网站,后端都只需提供前端所需的数据
  3. 前后端分离的模式下,不再有render或redirect,对外一律提供API数据(json|xml)
  4. 前端与后端两个独立的项目全部通过ajax请求进行交互

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bQINQFKN-1605052650191)(DRF–day1.assets/image-20200628100122921.png)]

接口API

  1. 接口就是一些预定好的函数或方法 ,目的是为了提供应用程序与开发人员基于软件|硬件访问一组数据的能力,但无需访问源码或理解我内部的原理
  2. 接口在web开发中是前后端工程师进行数据交互的媒介
  3. 在web开发的过程中,接口就是由 url地址、请求参数、响应数据组成

RESTFul架构

在长期的前后端分离的开发模式下,为了提高开发效率,大家都默认遵从了一种 REST规范,它提供了一套接口定义的良好的格式

1. RESTFul是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则与约束条件。不是必须遵从的,但有了它之后可以更好的开发出简介、逻辑清晰的接口
2. 只要遵从了REST规范设计的软件就是RESTFul架构
3. 前后端分离模式下建议使用RESTFul风格,但只是一种设计规范,可以不遵守

RESTFul规范

核心目的:设计出更优雅的url

  • API与用户的通信尽量使用HTTPS协议
  • 每一个url用来标识一个唯一的资源
传统url: https://127.0.0.1/user/get_user/?id=3  代表用户id5的用户信息
rest Url:https://127.0.0.1/user/get_user/1/  代表用户id1的用户信息
  • 请求方法
1. GET : 从服务器获取资源  查询
2. POST:在服务器新增资源  添加
3. PUT:更新服务器资源    修改
4. DELETE:删除服务器资源  删除
5. PATCH:更新部分资源		局部修改
  • 状态码
# 每一个http请求都会返回对应的状态信息,而RESTFul要求在返回数据时提供本次请求的状态码
# 返回的数据格式也有一定的要求
# 包含请求信息
  • 接口API的本质
# RESTFul就是为了设计一个良好的接口,而大家都遵从这些默认的规范可以节省大量的时间
1. 后端接受一个包含参数的url
2. 解析参数,并对请求做相应的处理
3. 将处理后的结果序列化成json
4. 按照一定的格式将数据返回到前端

2. 工具使用

Postman的使用

接口测试工具:可以帮助开发者模拟发送各种http请求以及参数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j2HmdBpr-1605052650194)(DRF–day1.assets/image-20200628112641573.png)]

CSRF装饰器

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt, csrf_protect

# 函数视图
1. @csrf_protect  # 全局禁用csrf的情况 为某个视图单独添加csrf认证
2. @csrf_exempt  # 为某个视图免除csrf认证

# 类视图
1. @method_decorator(csrf_exempt, name="dispatch")  # 让类视图免除csrf认证
1. @method_decorator(csrf_protect, name="dispatch")  # 让类视图添加csrf认证

Navicat连接sqllite

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ot1YUKUY-1605052650195)(DRF–day1.assets/image-20200628120110045.png)]

3. Django开发接口API

接口开发

  • urls
from django.urls import path

from app import views

urlpatterns = [
    # 类视图url的定义
    path("users/", views.UserView.as_view()),
    # 匹配携带参数的路由
    path("users/<str:id>/", views.UserView.as_view()),

]

  • Views.py
  1. django类视图可以通过请求的http方法的不同来匹配不同的函数执行
  2. url中的参数可使用kwargs.get(“参数名”)的形式获取
  3. 接口API在返回数据的时候需要指定数据的格式以及状态码
@method_decorator(csrf_exempt, name="dispatch")  # 让类视图免除csrf认证
class UserView(View):
    """
    类视图内部通过请求的方法来匹配到对应的内部的函数,从而进行对应的处理
    """

    def get(self, request, *args, **kwargs):
        """
        提供查询单个用户与多个用户的操作
        :param request:  用户id
        :return: 查询后的用户信息
        """

        # 获取用户的id
        user_id = kwargs.get("id")
        if user_id:  # 查询单个
            user_val = User.objects.filter(pk=user_id).values("username", "password", "gender").first()
            if user_val:
                # 如果查询出对应的用户信息,则将用户的信息返回到前端
                return JsonResponse({
                    "status": 200,
                    "message": "查询单个用户成功",
                    "results": user_val
                })
        else:
            # 如果没有传参数id  代表查询所有
            user_list = User.objects.all().values("username", "password", "gender")
            print(type(user_list))
            if user_list:
                return JsonResponse({
                    "status": 200,
                    "message": "查询所有用户成功",
                    "results": list(user_list),
                })

        return JsonResponse({
            "status": 500,
            "message": "查询失败",
        })

    def post(self, request, *args, **kwargs):
        """
        新增单个用户
        """
        username = request.POST.get("username")
        pwd = request.POST.get("password")
        try:
            user_obj = User.objects.create(username=username, password=pwd)
            return JsonResponse({
                "status": 201,
                "message": "创建用户成功",
                "results": {"username": user_obj.username, "gender": user_obj.gender}
            })
        except:
            return JsonResponse({
                "status": 500,
                "message": "创建用户失败",
            })

Django类视图源码

  1. 类视图中源码的入口是url中的as_view()方法,通过此方法处理传递过来的类视图对象
  2. 经过一系列处理后,调用dispatch方法进行视图的分发,进而匹配到类视图中对应的函数
# Django 请求流程总结
1. 前端发起访问请求,通过url匹配到对应的类视图
2. 类视图调用as_view()方法进行解析
3. 在as_view中实例化当前类视图为self
4. self对象 调用dispatch方法进行视图的分发
5. 在dispatch内部匹配到对应的类视图中的函数,执行对应的函数方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gBgv6Q7I-1605052650196)(DRF–day1.assets/image-20200628150121414.png)]

4. DRF初识

DRF全称DjangoRestFramework,是一个灵活强大的工具包,主要是用来构建RESTFul风格的web API,它是Django生态中默认的前后端分离开发的标准

官网:https://www.django-rest-framework.org/

Github: https://github.com/encode/django-rest-framework

DRF的搭建

# REST framework 需要以下内容:
    Python (3.5, 3.6, 3.7, 3.8)
	Django (1.11, 2.0, 2.1, 2.2, 3.0)
    
# 安装DRF 
	pip install djangorestframework==3.10.0

# 配置settings (必须)
INSTALLED_APPS = [
    ...
    'rest_framework',
]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Hy5tTw9-1605052650199)(DRF–day1.assets/image-20200628155006858.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jz6BQo8F-1605052650200)(DRF–day1.assets/image-20200628160333884.png)]

DRF的第一个案例

  1. DRF的APIView继承了django的View类,所以DRF的请求分发是调用了继承的父类的方法,本身并没有做实现
  2. DRF的视图最后返回了一个免除csrf认证的视图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hxwVkR5Q-1605052650200)(DRF–day1.assets/image-20200628161419865.png)]

from rest_framework.views import APIView
from rest_framework.response import Response

# 开发基于drf的视图
class UserAPIView(APIView):

    def get(self, request, *args, **kwargs):
        print("DRF GET VIEW")

        return Response("DRF GET SUCCESS")

    def post(self, request, *args, **kwargs):
        print("POST GET VIEW")

        return Response("POST GET SUCCESS")

DRF请求的生命周期

  1. DRF视图同样是在url中的as_view()方法作为入口,执行的是APIView中的as_view
  2. APIView类中的as_view方法中调用了父类(django)的as_view方法,APIView在最后返回了一个禁用csrf后的view
  3. 在父类的as_view方法中调用了self.dispatch()方法进行请求的分发,由于子类自己实现了dispatch方法,所以走子类自己的方法 APIView类中的dispatch方法
  4. DRF的dispatch方法进行了额外的功能的实现
  5. 完成处理后交给类属图进行逻辑的处理,得到响应的结果后返回到前台。
  • DRF核心dispatch方法
    # DRF的核心类
    def dispatch(self, request, *args, **kwargs):
        """
        `.dispatch()` is pretty much the same as Django's regular dispatch,
        but with extra hooks for startup, finalize, and exception handling.
        """
        # 将参数赋值给实例化对象
        self.args = args
        self.kwargs = kwargs
        # TODO DRF的请求模块 处理drf请求相关的
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request
        self.headers = self.default_response_headers  # deprecate?

        try:
            # 三大认证模块
            self.initial(request, *args, **kwargs)

            # Get the appropriate handler method
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed

            response = handler(request, *args, **kwargs)

        except Exception as exc:
            # 异常的捕获 一旦发生异常  在此处理
            response = self.handle_exception(exc)

        # 响应模块
        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response

5. Request模块

主要功能:用来获取不同请求的参数

入口:request = self.initialize_request(request, *args, **kwargs)

Request类

class Request:

    def __init__(self, request, parsers=None, authenticators=None,
                 negotiator=None, parser_context=None):
        assert isinstance(request, HttpRequest), (
            .format(request.__class__.__module__, request.__class__.__name__)
        )
        # request是django原生的请求对象  赋值给 DRF视图类对象作为属性 _request
        # self当前 DRF视图类对象
        self._request = request
        self.parsers = parsers or ()
        self.authenticators = authenticators or ()
        self.negotiator = negotiator or self._default_negotiator()
        self.parser_context = parser_context
        self._data = Empty
        self._files = Empty
        self._full_data = Empty
        self._content_type = Empty
        self._stream = Empty

DRF获取GET请求参数

class UserAPIView(APIView):

    def get(self, request, *args, **kwargs):
        # request:<rest_framework.request.Request>
        # get(self, request, *args, **kwargs):  DRF视图中的request事 经过封装后的request对象  其中包含原生的request
        # 可以通过_request 访问Django原生的request对象
        print(request._request.GET)		# 不推荐  知道即可
        # 通过DRF 的request对象获取参数
        print(request.GET)
        # 通过quer_params来获取参数  DRF扩展的
        print(request.query_params)
        
        # 获取路径传参
        user_id = kwargs.get("pk")
        
        return Response("DRF GET SUCCESS")

DRF获取POST请求参数

post请求中,不同格式的参数要通过不同的形式接收

class UserAPIView(APIView):

    def post(self, request, *args, **kwargs):
        # post请求传递参数的形式  form-data  www-urlencoded  json
        print(request._request.POST)  # Django 原生的request对象
        print(request.POST)  # DRF 封装后的request对象
        # 可以获取多种格式的参数 DRF 扩展的请回去参数  兼容性最强
        print(request.data)

        return Response("POST GET SUCCESS")

作业

1. 掌握django开发接口的方式,DRF开发接口的方法
		完成 查询单个用户的API  查询所有用户API  必做
		删除单个用户   修改单个用户  选做
2. 掌握django类视图请求流程
3. 掌握DRF视图请求源码流程
4. 掌握DRF获取参数的方式
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值