Django之DRF1

一、web应用模式

1.前后端混合开发

-后端人员,既要写后端,django,又要写前端

2.前后端分离

-后端人员,只写后端,写一个个的API接口

-前端人员,只写前端

-最后项目写完,前后端联调

 

二、API接口

1.为什么要有api接口

为了在团队内部形成共识、防止个人习惯差异引起的混乱,我们需要找到一种大家都觉得很好的接口实现规范,而且这种规范能够让后端写的接口,用途一目了然,减少双方之间的合作成本。

2.什么是api接口

通过网络,规定了前后台信息交互规则的url链接,也就是前后台信息交互的媒介,它称之为API接口
    -前端:向后端发送请求,获取数据   127.0.0.1:8080/index  --->返回数据
    -后端:请求某个地址,返回固定的数据

3.api接口的四大特点

四大特点
    -1 url链接:127.0.0.1:8080/index
    -2 有不同的请求方式:get、post、put、patch、delete
    -3 请求参数   127.0.0.1:8080/books?name=红楼梦   放在请求体中
    -4 响应结果: 一般是json格式,也可能是xml

三、接口测试工具

1.为什么要有接口测试工具

写好的接口,要测试,可以使用浏览器来做,但是浏览器只能发送get请求,接口有其他请求方式

2.都有什么接口测试工具

-postman :大部分公司用的,原来免费, 后来收费了,我们只用免费部分就够了

-postwomen

 -apifox

安装:官网下载安装包,双击运行,就安装完成

3.post请求的编码格式

-urlencoded 格式    ---》默认格式  b'xx=xx&yy=yy'
-form-data 格式     ---》传文件格式,也可以带数据--->251971281264627087498320--  带数据,带文件
 -json格式(用的最多)-->只能传数据 --->b'{"name":"lqz","age":18}'

如果是json形式提交数据----》django中想取,从request.POST取出到

 四、Resrful规范

1.什么是Resrful规范

RESTful是一种定义API接口的设计风格,AIP接口的编写规范,,尤其适用于前后端分离的应用模式中

这种风格的理念认为后端开发任务就是提供数据的,对外提供的是数据资源的访问接口,所以在定义接口时,客户端访问的URL路径就表示这种要操作的数据资源

我们可以使用任何一个框架都可以实现符合restful规范的API接口

2.Resrful 10条规范

1 数据的安全保障,通常使用https协议进行传输
    2 url地址中带接口标识:一般这样
    	-https://api.baidu.com
        -https://www.baidu.com/api
        
    3 多版本共存,url地址中带版本信息
    	https://api.baidu.com/v1/login/
		https://api.baidu.com/v2/login/
        
    4 数据即是资源,均使用名词:
        url地址尽量使用名词
        # 接口一般都是完成前后台数据的交互,交互的数据我们称之为资源
        https://api.baidu.com/users
        https://api.baidu.com/books
        https://api.baidu.com/book
        注:一般提倡用资源的复数形式,在url链接中不要出现操作资源的动词,错误示范:https://api.baidu.com/delete-user

        # 特殊的接口可以出现动词,因为这些接口一般没有一个明确的资源,或是动词就是接口的核心含义
        https://api.baidu.com/place/search
        https://api.baidu.com/login
        
    5  资源操作由请求方式决定
    	#操作资源一般都会涉及到增删改查,我们提供请求方式来标识增删改查动作
        https://api.baidu.com/books   - get请求:获取所有书
        https://api.baidu.com/books/1 - get请求:获取主键为1的书
        https://api.baidu.com/books   - post请求:新增一本书书
        https://api.baidu.com/books/1 - put请求:整体修改主键为1的书
        https://api.baidu.com/books/1 - delete请求:删除主键为1的书
        
   6  url地址中带过滤条件  ?后带过滤条件
		https://api.baidu.com/books -get请求表示查询所有图书,要查名字中有红的图书
    	https://api.baidu.com/books?name_contains=红
    	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 响应状态码(http响应中带状态码)
	-http的响应状态码:https://blog.csdn.net/meng2lin/article/details/128955775
    	-1xx:请求正在处理
        -2xx:请求成功 200  201
        -3xx:重定向
        -4xx:客户端错误
        -5xx:服务的错误
    -http的响应的数据中带状态码(公司自己规定的)
    	-{code:100}
        
   8 返回的数据中带错误信息
		{code:101,msg:用户名或密码错误}
    	{code:100,msg:成功}
        
   9 返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范
        GET  /books:返回资源对象的列表(数组)
    		-[{name:金瓶梅,price:88},{name:西游记,price:88}]
        	-{code:100,msg:成功,data:[{name:金瓶梅,price:88},{name:西游记,price:88}]}
        GET /books/1:返回单个资源对象
        	-{name:金瓶梅,price:88}    ---{code:100,msg:成功,data:{name:金瓶梅,price:88}}
        POST /books:返回新生成的资源对象
        	-{id:4,name:金瓶梅,price:88}  ---{code:100,msg:成功}
        PUT /books/4:返回完整的资源对象
        	-{id:4,name:金瓶梅,price:188}  ---{code:100,msg:修改成功}
        DELETE /books/4: 返回一个空文档      ---{code:100,msg:删除成功}
           
   10 返回的结果中带url链接

五、序列化和反序列化

api接口开发,最核心最常见的一个过程就是序列化

1.什么是序列化:把我们(python)识别的数据转换成指定的格式提供给别人。

例如:我们在django中获取到的数据默认是模型对象(queryset),但是模型对象数据无法直接提供给前端或别的平台使用,所以我们需要把数据进行序列化,变成字符串或者json数据,提供给别人。

2.什么是反序列化:把别人提供的数据转换/还原成我们需要的格式。

例如:前端js提供过来的json数据,对于python而言就是字符串,我们需要进行反序列化换成模型类对象,这样我们才能把数据保存到数据库中

序列化:drf称为 read      序列化
反序列化:drf称为 write   反序列化

六、drf介绍和快速使用

book表为例,写5个接口(后面你写的所有接口,都是这5个,及其变形)

先以普通写法cbv为例

1.数据库迁移

from django.db import models


# Create your models here.


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

2.-查询所有图书
    -新增一本图书
    -修改一本图书
    -查询一本图书
    -删除一本图书

views:

class BookViews(View):
    # 获取全部图书
    def get(self, request):
        book_obj = models.Books.objects.all()
        # print(book_list)
        book_list = []
        for book in book_obj:
            book_list.append({'name': book.name, 'price': book.price})
        return JsonResponse({'code': 200, 'msg': '成功', 'result': book_list})

    # 新增一本书
    def post(self, request):
        name = request.POST.get('name')
        price = request.POST.get('price')
        models.Books.objects.create(name=name, price=price)
        return JsonResponse({'code': 200, 'msg': '成功'})


class BookDetail(View):
    # 查询单条
    def get(self, request, pk):
        book = models.Books.objects.filter(pk=pk).first()
        book_dict = {'name': book.name, 'price': book.price}
        return JsonResponse({'code': 200, 'msg': '成功', 'result': book_dict})

    # 修改一条
    def put(self, request, pk):
        book = models.Books.objects.filter(pk=pk).first()
        # res = json.loads(request.body)
        # models.Books.objects.filter(pk=pk).update(name=res['name'], price=res['price'])
        print(json.loads(request.body))
        return JsonResponse({'code': 200, 'msg': '成功'})

    # 删除一本书
    def delete(self, request, pk):
        models.Books.objects.filter(pk=pk).delete()
        return JsonResponse({'code': 200, 'msg': '成功'})

urls:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', BookViews.as_view()),
    path('books/<int:pk>/', BookDetail.as_view()),
]

drf介绍

django 中有个app,djangorestframework:drf,帮助我们,快速实现符合resful规范的接口

1.下载

pip3.8 install djangorestframework==稍微将版本

如果你是django2, 直接这样装,装最新drf,他们不匹配---》pip会自动把django卸载,安装最新django,安装最新drf

强制更新

pip3.8 install djangorestframework --upgrade

补充:

-如果写了一个包,或app,想给别人用---》把你写的包,放到pypi上别人pip install 安装---》使用

drf快速使用

urls:

from app01.views import BookView
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register('books', BookView, 'books')
urlpatterns = [
]
urlpatterns += router.urls

views:

from .models import Books
from .serializer import BookSerializer
from rest_framework.response import Response


from .serializer import BookSerializer
from rest_framework.viewsets import ModelViewSet
class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

序列化类serializer.py

from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

基于APIView的5个接口

urls:

from app01.views import BookView
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register('books', BookView, 'books')
urlpatterns = [
]
urlpatterns += router.urls

views:

from rest_framework.views import APIView  # APIView继承了djagno原来的View
from .serializer import BookSerializer
from rest_framework.response import Response


class BookView(APIView):
    # 查询所有
    def get(self, request):
        book_list = Book.objects.all()
        # drf提供了序列化类
        ser = BookSerializer(instance=book_list, many=True)  # 序列化
        return Response({'code': 100, 'msg': '成功', 'result': ser.data})

    def post(self, request):
        ser = BookSerializer(data=request.data)  # 反序列化
        if ser.is_valid():  # 数据校验---》有些不合法的禁止
            ser.save()  # 保存到数据库中
        return Response({'code': 100, 'msg': '成功'})


class BookDetailView(APIView):
    # 查询单条
    def get(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=book, many=False)  # 序列化
        return Response({'code': 100, 'msg': '成功', 'result': ser.data})

    # 修改一条
    def put(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=book, data=request.data)  # 反序列化
        if ser.is_valid():  # 数据校验---》有些不合法的禁止
            ser.save()  # 保存到数据库中
        return Response({'code': 100, 'msg': '成功'})

    def delete(self, request, pk):
        Book.objects.filter(pk=pk).delete()
        return Response({'code': 100, 'msg': '删除成功'})

序列化类serializer.py:

from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

七、CBV源码分析

cbv写法:
    1 视图中写视图类,继承View,写跟请求方式同名的方法

class BookView(View):
            def get(self,request):
                return 四件套

2 在路径用写

path('books/', BookView.as_view())

如上写法,为什么能够执行

# 前置条件:前端请求,一旦路径匹配成功,就会执行  BookView.as_view()(request传入,)
# 入口在  BookView.as_view()--->执行结果---》View中有个as_view类的绑定方法
    @classmethod
    def as_view(cls, **initkwargs):
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            res=self.dispatch(request, *args, **kwargs)
            return res
        return view
    
# 执行结果是view 的内存地址: 请求来了,执行view(request)
	path('books/', view)
    
# 执行 View类中的as_view方法中的内层的view函数,路由匹配成功,本质是在执行
	self.dispatch(request, *args, **kwargs)
    # self是谁的对象?BookView的对象
    # 去BookView中dispatch,找不到,去父类,View中找到了
    
    
# View这个类的dispatch
    def dispatch(self, request, *args, **kwargs):
        # request.method.lower() 如果是get请求,  ‘get’ 在这个列表里面
        if request.method.lower() in self.http_method_names:
            # handler=getattr(BookView的对象,'get')   
            # handler就是BookView类中的get方法
            handler = getattr(self, request.method.lower())
        else:
            handler = self.http_method_not_allowed
        # 执行 BookView类中的get方法 (request)
        return handler(request, *args, **kwargs)
    
# 最终本质跟写fbv的执行流程一样
# 最终结论:什么请求方式,就会执行视图类中的什么方法

APIView执行流程分析

# 有了drf,后期都写CBV,都是继承APIView及其子类
# 执行流程:
	-入口:path('books/', BookView.as_view())---》请求来了,执行BookView.as_view()(request)
    -as_view 是谁的? APIView的as_view
        @classmethod
        def as_view(cls, **initkwargs):
            # super()代指的是:父类对象  View类的对象
            # View的as_view(**initkwargs)----》执行结果是view,是View类的as_view方法中的view
            view = super().as_view(**initkwargs)
            view=csrf_exempt(view)  # 局部禁用csrf,
            return view
        
  	-path('books/', View类的as_view中的view,只是去掉了csrf的认证)
	-请求来了,执行 【View类的as_view中的view,只是去掉了csrf的认证(request)】
    -执行:self.dispatch(request, *args, **kwargs),  self要从根上找
	-self.dispatch 是APIView的dispatch,源码如下
        def dispatch(self, request, *args, **kwargs):
            # request 是新的request,      request是老的request
            request = self.initialize_request(request, *args, **kwargs)
            self.request = request
            try:
                # 执行了认证,权限和频率
                self.initial(request, *args, **kwargs)
                # 在执行视图类方法之前,去掉了csrf认证,包装了新的request,执行了认证频率和权限
                #### 执行请求方式字符串对应的方法
                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

总结:

1  以后只要继承APIView的所有视图类的方法,都没有csrf的校验了
2  以后只要继承APIView的所有视图类的方法 中的request是新的request了
3  在执行视图类的方法之前,执行了三大认证(认证,权限,频率)
4  期间除了各种错误,都会被异常捕获,统一处理

补充(装饰器语法糖):
    fbv,局部禁用csrf,如何写?

@csrf_exempt
    def index(request):
        pass


本质原理是(装饰器本质):index=csrf_exempt(index)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django中使用DRFDjango Rest Framework)需要进行以下配置: 1. 安装DRF 可以通过pip安装DRF,命令如下: ``` pip install djangorestframework ``` 2. 在INSTALLED_APPS中添加'rest_framework' 在settings.py中的INSTALLED_APPS列表中添加'rest_framework',如下所示: ``` INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'myapp', ] ``` 3. 配置REST_FRAMEWORK设置 在settings.py中添加REST_FRAMEWORK设置,以配置DRF的一些选项,如下所示: ``` REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.BrowsableAPIRenderer', ], } ``` 以上设置包括了DRF中的默认身份验证类、默认权限类和默认渲染器类。可以根据需要进行修改。 4. 创建序列化器 在myapp中创建一个serializers.py文件,定义一个序列化器类,如下所示: ``` from rest_framework import serializers from myapp.models import MyModel class MyModelSerializer(serializers.ModelSerializer): class Meta: model = MyModel fields = '__all__' ``` 5. 创建视图 在myapp中创建一个views.py文件,定义一个视图类,如下所示: ``` from rest_framework import generics from myapp.models import MyModel from myapp.serializers import MyModelSerializer class MyModelList(generics.ListCreateAPIView): queryset = MyModel.objects.all() serializer_class = MyModelSerializer ``` 以上视图类继承了DRF提供的generics.ListCreateAPIView类,用于实现查询和创建操作。可以根据需要进行修改。 6. 创建URL 在myapp中的urls.py文件中定义一个URL,将视图类和URL绑定在一起,如下所示: ``` from django.urls import path from myapp.views import MyModelList urlpatterns = [ path('mymodel/', MyModelList.as_view(), name='mymodel-list'), ] ``` 以上是Django使用DRF的基本配置。可以根据项目需求进行调整和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值