首页 > 编程语言 > 详细

python - Django - restframework 简单使用 和 组件

时间:2019-02-27 20:42:49      阅读:182      评论:0      收藏:0      [点我收藏+]

FBV 和 CBV

CBV 通过函数调用方法
FBV 通过类调用方法
    其本质上都是 CBV
但是 FBV 内部封装了关于 method 的方法,由于基本上都是前端的请求,所有像GET,POST等方法用的频繁,
而FBV将这些方法封装了起来,使得开发时更便捷了许多,所以FBV更适合写接口

######  标准的  ######
2.1 fbv方式请求的过程

用户发送url请求,Django会依次遍历路由映射表中的所有记录,一旦路由映射表其中的一条匹配成功了,
就执行视图函数中对应的函数名,这是fbv的执行流程

2.2 cbv方式请求的过程

当服务端使用cbv模式的时候,用户发给服务端的请求包含url和method,这两个信息都是字符串类型

服务端通过路由映射表匹配成功后会自动去找dispatch方法,然后Django会通过dispatch反射的方式找到类中对应的方法并执行

类中的方法执行完毕之后,会把客户端想要的数据返回给dispatch方法,由dispatch方法把数据返回经客户端

 

一:下载

pip install djangorestframewrok

 

二:Views

    # restframework 常用的类
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
from rest_framework.viewsets import GenericViewSet
from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response

写法1:

--
    from rest_framework import serializers
    (1)和 models 表中的字段对应 (使用模块:serializers.Serializer)
    (2)全部字段直接写(使用模块:serializers.ModelSerializer) 
        class Meta:
        model = models.Book
        fields = __all__
    (3)使用时需要调用 BookModelSerializers(queryset/data,many=True/False)
    注:当需要返回一个 queryset 的时候必须加 many=True 这个参数,单条数据则不用
 --
 ----------Url----------
 from app01 import views
 re_path(book/$,views.BookView.as_view())

 ----------View----------
from rest_framework import serializers
class BookModelSerializers(serializers.ModelSerializer):
    title = serializers.CharField()
    price = serializers.CharField()
    publish = serializers.CharField()

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

# 更新操作:
def put(self,request,pk):
    shop = models.Shop.objects.filter(pk=pk).first()
    bs = ShopSerializers(shop,data=request.data)
    if bs.is_valid():   # 判断数据是否有误
        print(bs: ,bs)
        bs.save()       # 相当于调用了 updata方法
    return Response(bs.data)    # 返回 数据
    else:
        return Response(bs.errors)

# 添加操作:
ps = PublishSerializers(data=request.data)
if ps.is_valid():
   ps.save()  # create

# 查询操作:
class BookView(APIView):
    def get(self,request):
        book_list = models.Book.objects.all()
        serializers = BookModelSerializers(book_list,many=True)
        return Response(serializers.data)

# 删除操作:
def delete(self,request,pk):
    models.Shop.objects.filter(pk=pk).delete()
    return Response()

 

写法2:

--
(a)
   (1)mixins    模块中有 List,Create,Put...方法可以直接使用
   (2)generics  主要作用还是调用 APIView 中的
--

----------Url----------
 from app01 import views
 re_path(book/$,views.BookView.as_view())

 ----------View (a)---------- 
from rest_framework import mixins
from rest_framework import generics
from rest_framework import serializers

from rest_framework import serializers
class BookModelSerializers(serializers.ModelSerializer):
    title = serializers.CharField()
    price = serializers.CharField()
    publish = serializers.CharField()

class AuthorView(mixins.ListModelMixin,generics.GenericAPIView):
    queryset = models.Author.objects.all()      # 必须有的参数 :queryset
    serializer_class = AuthorModelSerializers   # 必须有的参数 :serializer_class

    def get(self,request,*args,**kwargs):
        return self.list(request,*args,**kwargs)

--
(b)
   (1)继承 generics.RetrieveUpdateDestroyAPIView 
       将上面的 mixins generics 全部封装成了一个模块
--

 ----------View (b)---------- 比上面简单一点
class UserView(generics.RetrieveUpdateDestroyAPIView):
    queryset = models.User.objects.all()
    serializer_class = UserModelSerializers

 

写法三:

--
    (1) as_view({参数})
    中传的参数是必须的,参数的名称还是固定的,
    可根据需求来限定哪个url配定哪个参数
    (2) view 中 的变量名也是固定的,不能改变,
        当执行到某个父类的方法的时候,就会需要这两个参数
        queryset      -- queryset
    serializer_class 
--
----------Url----------
from app01 import views
re_path(book/$, views.Book.as_view({get: list, post: create})),
re_path(book/(?P<pk>\d+)/$, views.Book.as_view({get: retrieve, put: update,delete:destroy})),

----------View----------

from rest_framework import viewsets

class Book(viewsets.ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = BookModelSerializers

 

四:认证组件

----------  View(局部认证)  ----------
--
    (1) BaseAuthentication 模块中 有俩个方法(authenticate , authenticate_header)
        注:这俩个方法也是固定名字,两个必须写上,一个都不能少,否则报错 !
              模块中这两个方法都是返回空的,但是执行的时候当前函数就将
              两个方法覆盖了,也就是少些一个 authenticate_header
    (2) 创建一个 返回 随机字符的 token

    (3) update_or_create -- 如果有就更新,如果没有就创建
                
--

# 认证 组件
from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication
from app01 import models
class TokenAuth(BaseAuthentication): # 这个方法直接写在一个文件中
    def authenticate(self,request):
        token = request.GET.get(token)  # 获取 token
        token_obj = models.Token.objects.filter(token=token).first()  # 验证 token 是否匹配
        if not token_obj:
            raise exceptions.AuthenticationFailed(验证失败)
        else:
            return token_obj.user.name,token_obj.token


# 返回一个 登陆校验判断 的随机字符串
def get_random_str(user):
    import hashlib,time
    ctime = str(time.time())    # 当前时间字符串

    md5 = hashlib.md5(bytes(user,encoding=utf8))  # md5 加密,加盐
    md5.update(bytes(ctime,encoding=utf8))        # 将字符串进行拼接

    #md5.digest()     二进制
    #md5.hexdigest()  十六进制
    return md5.hexdigest()  # 返回一个 十六进制 的加密随机字符

# 登陆验证
class LoginView(APIView):
    authentication_classes = [TokenAuth]  
    def post(self,request):
        name = request.data.get(name)    # 获取用户名
        pwd = request.data.get(pwd)    # 获取密码
        user = models.User.objects.filter(name=name,pwd=pwd).first()  # 数据库校验
        res = {code:0,msg:None}
        if user:
            random_str = get_random_str(user.name)
            token = models.Token.objects.update_or_create(user=user,defaults={token:random_str}) # 在数据库生成 token
            res[token] = random_str
            res[code] = 1
            res[msg] = 验证成功
        else:
            res[msg] = 验证失败
        import json
        return Response(json.dumps(res))


----------  View(全局认证)  ----------

(1) settings 中配置 认证组件位置:
    
# 全局认证组件
REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.TokenAuth",]
}

(2) 这样就不用写 authentication_classes = [TokenAuth] 
(3) 如果哪个方法不需要认证的话 只需要 authentication_classes = [] 将列表设为空

 

五:权限组件

# 权限组件
class SvipPermission(object):  # 这个方法直接写在一个文件中
    message = "只有超级用户才能访问"
    def has_permission(self,request,view):
        username = request.user
        user_type = models.User.objects.filter(name=username).first().user_type
        if user_type == 3:
            return True     # 返回True 则验证通过
        else:
            return False    # 返回False 则验证不通过

# 只需类下面添加
permission_classes = [SvipPermission] # 权限组件 -- 局部

# 全局认证
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES":[‘app01.utils.SvipPermission‘], # 全局权限组件
}

 

六:解析器 (用于将解析字符格式)

 

from rest_framework.parsers import JSONParser,FormParser
 parser_classes = [JSONParser, FormParser]  # 局部 (用于将解析字符格式)

 

 

七:分页器 -- 用于调试 restframework 返回的页面

# 要使用 restframework 自带的调试数据网页 需要在 settings 中配置
INSTALLED_APPS = [
‘django.contrib.admin‘,
‘django.contrib.auth‘,
‘django.contrib.contenttypes‘,
‘django.contrib.sessions‘,
‘django.contrib.messages‘,
‘django.contrib.staticfiles‘,
‘app01.apps.App01Config‘,
‘rest_framework‘,  # 配置 restframework 组件
]


#
分页器 from rest_framework.pagination import PageNumberPagination class BookPageNumberPagination(PageNumberPagination): page_size = 1 # 每页显示个数 page_query_param = page page_size_query_param = size # 修改当前页显示个数 #max_page_size = 2 # 每页显示个数限制 class BookView(APIView): def get(self,request): book_list = models.Book.objects.all() # 分页器 pnp = BookPageNumberPagination() book_page = pnp.paginate_queryset(book_list,request,self) bs = BookModelSerializers(book_page,many=True,context={request: request}) return Response(bs.data)

 

python - Django - restframework 简单使用 和 组件

原文:https://www.cnblogs.com/chaoqi/p/10446586.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!