导入drf_Django后端rest最简洁最快最全入门指南,1天学会DRF后端不夸张,看这篇就够了!!...

d3894bff3064b1879713ffbe6608f763.png

Django REST framework

模型

字段类型

#BooleanField
# CharField(max_length=none[, **options])
# DateField  DateTimeField([auto_now=False, auto_now_add=False, **options]) ##自动更新 自动创建
# DecimalField(max_digits=None,decimal_places=None[, **options]) 小数点
# BinaryField
#ImageField([upload_to=None, height_field=None, width_field=None, max_length=100, **options]) 需要安装pillow模块
#EmailField([maxlength=75, **options])
#FileField(upload_to=None[, max_length=100, **options])  默认的form widget 是 FileInput
#FloatField
#IntegerField #整数
#IPAddressField
#GenericIPAddressField
#NullBooleanField
#PositiveIntegerField 正证书
#SlugField url常用  只能包含字母,数字,下划线和连字符的字符串
#TextField 大文本
#TimeField
#URLField
#FilePathField(path=None[, match=None, recursive=False, max_length=100, options])
## ProcessedImageField 使用imagekit模块

模型filed选项

#editable  #error_messages  #help_text  
#primary_key  radio_admin  unique
#unique_for_date  #unique_for_month 
#unique_for_year
#validators
#db_index=True 创建索引
#verbose_name  string类型。更人性化的列名。
## 获取drf模板源码交流学习 联系作者wechat yihongwxh 

序列器

决定输入输出结构

常规示例写法

id = serializers.IntegerField(label='ID', read_only=True)

一般验证

使用模型序列器,extra_kwargs 来给字段加验证

class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task
        #read_only_fields = ( 'date',)
        # fields = '__all__' 输出所有模型
        # exclude = ('image',) 排除模型
        fields = ('q','a',"link","myfile","choice","myimg")
        extra_kwargs = {#额外参数 指定最大最小值
            'q': { 'required': True,'label':u"问题"},      #可使用的额外参数 label='阅读量', max_value=2147483647, min_value=0, required=True
            'a': { 'required': True,'max_length':5,'help_text': u'帮助介绍'},       #read_only=True   max_length=20
        }
## 获取drf模板源码交流学习 联系作者wechat yihongwxh 

单独某个字段验证

def validate_q(self, attrs):  ##validate+字段名进行序列验证
    if 's' not in attrs:
        raise serializers.ValidationError(u'必须包含s')
    return attrs

多字段验证

def validate(self, attrs): # 给多个字段增加校验
    bread = attrs['bread']
    bcomment = attrs['bcomment']
    if bread < bcomment:
        raise serializers.ValidationError('阅读量小于评论量')
    return attrs

常规序列器与模型序列器

自动生成字段 validators 包含create()和update()方法

视图

默认视图APIVIEW

class BookView(APIView):  ##需要自定义get,post,patch,delete方法
​
    def get(self, request):
        query_set = Book.objects.all()
        book_ser = BookSerializer(query_set, many=True)
        return Response(book_ser.data)
​
    def post(self, request):
        query_set = request.data
        book_ser = BookSerializer(data=query_set)
        if book_ser.is_valid():
            book_ser.save()
            return Response(book_ser.validated_data)
        else:
            return Response(book_ser.errors)
## 获取drf模板源码交流学习 联系作者wechat yihongwxh 

封装过的GenericAPIView

# 默认使用queryset   serializer_class 
# 包含5个mixin 封装了get,post,patch,delete方法 对应ListModelMixin, CreateModelMixin,GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
# 5个mixin封装成2个apiview  ListCreateAPIView  RetrieveUpdateDestroyAPIView

使用viewsetmixin带action路由传参封装成modelviewset

class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

使用action进行自定义路由

@action(methods=['get','post'],detail=False)   ##自定义方法
# action是drf提供的路由和视图方法绑定关系的装饰器
# 参数2: detail  当前是否方法是否属于详情页视图,False,系统不会自动增加pk在生成的路由地址中  True  则系统会自动增加pk在生成的路由地址
def query(self,request):  # 其接口 http://127.0.0.1:8000/task/query/
    # 获取阅读量最多的5条数据
    para= request.query_params          ## request.data post put 参数
    books = Task.objects.filter(q__contains =para['q']) # 多条查询使用Q    #table.object.filter(Q(title__startswith='key1') | Q(title__startswith='key2'))
    serializer = TaskSerializer(instance=books,many=True)
    return Response(serializer.data)

queryset查询语句

##filter内容
# Blog.objects.filter(title__contains ="django")
#.objects.filter(id__in = [3,6,9])
#.objects.filter(id__range =(30,45))
#.objects.exclude(id=3)
#.objects.filter(create_time__year = 2018)
#objects.filter(create_time__month=3)
#.objects.dates('create_time', 'year','DESC') 返回时间
##__gt gte lt lte startswith  endswith

获取请求数据

#request.query_params 存放的是我们get请求的参数
#request.data 存放的是我们所有的数据,包括post请求的以及put,patch请求
##默认django方法request.POST.get()  request.GET.get("pid")
##请求方法判断 request.method

响应

# Response(content, status=status.HTTP_404_NOT_FOUND)
# 状态码的种类....

自定义排序搜索过滤器

class TaskView(ModelViewSet):
    filter_class = MyFilter
    ordering_fields = ('q', 'choice')      ##?ordering=price,name  查询 按照 price 排序后 在按 name 排序的结果 支持升序和降序 加-号即可
	search_fields = ('q', 'a', 'link')  # 模糊搜索 加入对应字段即可
##需要在全局setting.py导入
INSTALLED_APPS = [
    'django_filters',
]
##排序搜索器导入setting.py 全局配置
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 20,
    'DEFAULT_FILTER_BACKENDS':[
            'rest_framework.filters.OrderingFilter',
            'django_filters.rest_framework.DjangoFilterBackend',
            'rest_framework.filters.SearchFilter'
                               ],
}

路由

一般APIview写法

urlpatterns = [
    url(r'^book$', BookView.as_view({"get": "list", "post": "create"})),
    url(r'^book/(?P<pk>d+)$', BookView.as_view({"get": "retrieve", "patch": "update", "delete": "destroy"})),
]
###默认使用参数pk传递 指定get patch update delete 对应函数名

modelviewset路由自动注册

router = DefaultRouter()
router.register(r"book", BookView)
##自动注册5个方法,

权限设置RBAC

修改全局设置

##修改全局setting 
AUTHENTICATION_BACKENDS = [
    'account.backend.Mybackend',
    'django.contrib.auth.backends.ModelBackend',
]
​
AUTH_USER_MODEL = 'account.MyUser' 

注册admin跟user role permission模型

#admin.py 注册
admin.site.register(MyUser, UserAdmin)
#backend.py 示例
class Mybackend(ModelBackend):
    def authenticate(self, username=None, password=None):
        if username and password:
            user = get_user_model().objects.filter(username=username).first()
            if user and user.check_password(password):
                return user
##创建3个模型 user role permission  分别嵌套     
roles = models.ManyToManyField("Role", verbose_name="角色", blank=True)

服务端token生成

##登录验证返回token   
##登录视图
class LoginView(APIView):
    serializer_class = LoginSerializer
    def post(self, request):
        serializer = LoginSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)
        return Response({'token': token.key})
#登录序列器
class LoginSerializer(serializers.Serializer):
    username = serializers.CharField(required=True, error_messages={'blank': u'用户名不能为空'})
    password = serializers.CharField(
        style={'input_type': 'password'}, required=True, error_messages={'blank': u'密码不能为空'})
    def validate(self, attrs):
        username, password= attrs['username'], attrs['password']
        user = authenticate(username=username, password=password)
        if not user:
            raise ValidationError(u'用户名或者密码错误')
        attrs['user'] = user
        return attrs
## 获取drf模板源码交流学习 联系作者wechat yihongwxh 

前端传token

## header中传入 Authorization: Token 5e8341bfc3bda41f169ef6ee15613bca47619a44

封装的permission检查方法

perms_map = (('*', '*', '会员'), ('list', '*', '普通用户'),   ##*表示能没有权限限制
             ('create', 'VIP', '会员'), ('update', 'VIP', '会员'),
             ('destroy', 'VIP','会员'),('query', "*", "查询"),)
### 传入perms_map list create update distory 以及自定义方法对应的权限方法 作为第二个参数传入
permission_classes = [RbacPermission, ]

一般权限

class RbacPermission(BasePermission):  ##一般权限
    def get_current_method(self, request, view):
        """
        获取当前请求的方法(当前请求的是post/get 还是 viewset 的 action)
        :param request:
        :param view:
        :return:
        """
        return hasattr(view, 'action') and getattr(view,'action') or request._request.method.lower()
    @classmethod  ##不需要实例化直接调用
    def get_permission_from_role(cls, request):
        try:
            perms = request.user.roles.values('permissions__name', ).distinct()  ##后面的权限方法都写在method中
            return [p['permissions__name'] for p in perms]   ##写入到权限方法中去
        except AttributeError:
            return []
    def get_current_perms(self, request, view):
        """
        获取当前需要验证的权限
        :return:
        """
        _method = self.get_current_method(request, view)
        perms_map = view.perms_map
        # name_or_perm_obj 可能是权限名称,也可能是基于BasePermission的权限扩展实例
        try:
            action, name_or_perm_obj, label = [(action, name_or_perm_obj, label)
                                               for action, name_or_perm_obj, label in perms_map
                                               if action == _method][0]
        except IndexError:
            return True
        print  name_or_perm_obj
        return name_or_perm_obj
    def has_permission(self, request, view):
        if request.user.is_superuser:
            return True
​
        if not hasattr(view, 'perms_map'):  ##搜集所需权限列表
            return True
        name_or_perm_obj = self.get_current_perms(request, view)
        if isinstance(name_or_perm_obj, BasePermission):
            return name_or_perm_obj.has_permission(request, view)  ##权限对象检查
        return self.has_name_in_perms(name_or_perm_obj, request)  ##字段检查
    def has_name_in_perms(self, perm_name, request):  ##检查用户有没有这个权限
        perms = self.get_permission_from_role(request)
        return perm_name == '*' or perm_name in perms

对象权限

class ObjPermission(BasePermission):  ###通过用户id来检查
    def has_object_permission(self, request, view, obj):
        if request.user.is_superuser:
            return True
        elif request.user.id == obj.uid_id:
            return True

全局配置选项

MEDIA_URL = '/media/'  ##媒体文件上传路径
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
LANGUAGE_CODE = 'zh-hans' #语言

文档写作

class TaskView(ModelViewSet):
    ''' ##markdown  使用说明'''
@swagger_auto_schema(method='get',operation_description='查询单个详细参数')
​
## swagger路由配置及后端登录接口
    url(r'^swagger(?P<format>.json|.yaml)$', schema_view.without_ui(cache_timeout=0),
      name='schema-json'),
    url(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
    url(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
    url(r'^api/', include('rest_framework.urls', namespace='rest_framework_docs')),

插件

drf-ysag

django_filters

imagekit

常用导入头

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
##视图类
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView,ListCreateAPIView,RetrieveUpdateDestroyAPIView
from rest_framework.mixins import  ListModelMixin, CreateModelMixin,RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
from rest_framework.viewsets import ViewSetMixin
from rest_framework.viewsets import ModelViewSet
import  django_filters  ##过滤器
from rest_framework.decorators import action
from rest_framework import routers, serializers
from rest_framework.response import Response  ##响应
from django.conf import settings
from rest_framework import routers, serializers, viewsets
from django.contrib.auth import authenticate  ##认证
from rest_framework.authtoken.models import Token  ##token导入
from rest_framework.exceptions import ValidationError  ##序列化出错返回
##路由
from django.conf.urls import url, include
from rest_framework.routers import DefaultRouter  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值