zoukankan      html  css  js  c++  java
  • TEST framework(1)

    1. 什么是REST

    • REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征致使这些应用转变状态
    • REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
    • 所有的数据,不过是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性
    • 对于REST这种面向资源的架构风格,有人提出一种全新的结构理念,即:面向资源架构(ROA:Resource Oriented Architecture)

    2. 什么是 Django REST framework

    Django REST framework是一个基于Django开发的app,用于快速搭建REST API。

    安装:

    pip3 install djangorestframework

    a. 快速使用

    INSTALLED_APPS = [
        ...
        'rest_framework',
    ]
    1.注册APP
    from rest_framework import routers
    from . import views
    
    
    router = routers.DefaultRouter()
    router.register(r'users', views.UserInfoViewSet)
    
    urlpatterns = [
        url(r'^', include(router.urls)),
    ]
    2.注册路由
    from rest_framework import viewsets
    from . import models
    from . import serializers
    
    # ########### 1. 基本处理方式 ###########
    
    class UserInfoViewSet(viewsets.ModelViewSet):
        """
        API endpoint that allows users to be viewed or edited.
        """
        queryset = models.UserInfo.objects.all().order_by('-id')
        serializer_class = serializers.UserInfoSerializer
    3.编写ViewSet,视图函数
    from rest_framework import serializers
    from . import models
    
    class UserInfoSerializer(serializers.HyperlinkedModelSerializer):
        class Meta:
            model = models.UserInfo
            # fields = ('id', 'username', 'pwd','ug') # fields = '__all__'
            exclude = ('ug',)
            depth = 1  # 0<=depth<=10
    4.编写serializers,form验证以及数据库操作

    PS:最终访问路径

    [GET]          http://127.0.0.1:8000/api/users/
    [POST]         http://127.0.0.1:8000/api/users/
    [GET]          http://127.0.0.1:8000/api/users/7/
    [PUT]          http://127.0.0.1:8000/api/users/7/
    [DELETE]       http://127.0.0.1:8000/api/users/7/

    b. 基于CBV

    from django.conf.urls import url,include
    from django.contrib import admin
    from . import views
    
    urlpatterns = [
        url(r'^users/$', views.UserList.as_view()),
        url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
    ]
    1.URL
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from rest_framework.request import Request
    from rest_framework.parsers import JSONParser
    from . import models
    from . import serializers
    
    
    class UserList(APIView):
        def get(self, request, *args, **kwargs):
            user_list = models.UserInfo.objects.all()
            serializer = serializers.MySerializer(instance=user_list, many=True)
            return Response(serializer.data)
    
        def post(self, request, *args, **kwargs):
            data = JSONParser().parse(request)
            serializer = serializers.MySerializer(data=data)
            if serializer.is_valid():
                # print(serializer.data)
                # print(serializer.errors)
                # print(serializer.validated_data)
                # 如果有instance,则执行update方法;否则,执行create
                serializer.save()
                return Response(serializer.data, status=201)
            return Response(serializer.errors, status=400)
    
    
    class UserDetail(APIView):
        def get(self, request, *args, **kwargs):
            obj = models.UserInfo.objects.filter(pk=kwargs.get('pk')).first()
            serializer = serializers.MySerializer(obj)
            return Response(serializer.data)
    
        def delete(self, request, *args, **kwargs):
            obj = models.UserInfo.objects.filter(pk=kwargs.get('pk')).first()
            obj.delete()
            return Response(status=204)
    
        def put(self, request, *args, **kwargs):
            data = JSONParser().parse(request)
            obj = models.UserInfo.objects.filter(pk=kwargs.get('pk')).first()
            serializer = serializers.MySerializer(obj, data=data)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data)
            return Response(serializer.errors, status=400)
    2.编写视图函数
    from rest_framework import serializers
    from rest_framework.exceptions import ValidationError
    from . import models
    
    
    class MySerializer(serializers.Serializer):
        id = serializers.IntegerField(read_only=True)
        username = serializers.CharField(required=False, allow_blank=True, max_length=100)
        pwd = serializers.CharField()
    
        def validate_username(self, value):
            if value == '中国':
                raise ValidationError('用户名中存在敏感字符')
            return value
    
        def validate_pwd(self, value):
            print(value)
            return value
    
        def validate(self, attrs):
            print(attrs)
            return attrs
    
        def create(self, validated_data):
            """
            当执行save方法时,自动调用。instance未传值
            :param validated_data:
            :return:
            """
            print(validated_data)
            return models.UserInfo.objects.create(**validated_data)
    
        def update(self, instance, validated_data):
            """
            当执行save方法时,自动调用。instance传值
            :param instance:
            :param validated_data:
            :return:
            """
            instance.username = validated_data.get('username', instance.username)
            instance.save()
            return instance
    3.编写serializers

    c. 基于FBV

    from django.conf.urls import url,include
    from django.contrib import admin
    from . import views
    
    urlpatterns = [
        url(r'^users/$', views.user_list),
        url(r'^users/(?P<pk>[0-9]+)/$', views.user_detail),
    ]
    1.URL
    from django.http import JsonResponse,HttpResponse
    from rest_framework.response import Response
    from rest_framework.parsers import JSONParser
    from rest_framework.decorators import api_view
    from .serializers import MySerializer
    from . import models
    
    @api_view(['GET',"POST"])
    def user_list(request):
        """
        List all code snippets, or create a new snippet.
        """
        if request.method == 'GET':
            user_list = models.UserInfo.objects.all()
            serializer = MySerializer(user_list,many=True)
            return Response(serializer.data)
    
        elif request.method == 'POST':
            data = JSONParser().parse(request)
            serializer = MySerializer(data=data)
            if serializer.is_valid():
                print(serializer.data)
                print(serializer.errors)
                print(serializer.validated_data)
                # 如果有instance,则执行update方法;否则,执行create
                serializer.save()
                return Response(serializer.data, status=201)
            return Response(serializer.errors, status=400)
    
    @api_view(['GET',"POST","PUT"])
    def user_detail(request, pk):
        """
        Retrieve, update or delete a code snippet.
        """
    
        obj = models.UserInfo.objects.filter(pk=pk).first()
        if not obj:
            return HttpResponse(status=404)
    
        if request.method == 'GET':
            serializer = MySerializer(obj)
            # return JsonResponse(serializer.data,json_dumps_params={'ensure_ascii':False},content_type='application/json;charset=utf-8')
            return Response(serializer.data)
    
        elif request.method == 'PUT':
            data = JSONParser().parse(request)
            serializer = MySerializer(obj, data=data)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data)
            return Response(serializer.errors, status=400)
    
        elif request.method == 'DELETE':
            obj.delete()
            return Response(status=204)
    2.视图函数
    from rest_framework import serializers
    from rest_framework.exceptions import ValidationError
    from . import models
    
    
    class MySerializer(serializers.Serializer):
        id = serializers.IntegerField(read_only=True)
        username = serializers.CharField(required=False, allow_blank=True, max_length=100)
        pwd = serializers.CharField()
    
        def validate_username(self, value):
            if value == '中国':
                raise ValidationError('用户名中存在敏感字符')
            return value
    
        def validate_pwd(self, value):
            print(value)
            return value
    
        def validate(self, attrs):
            print(attrs)
            return attrs
    
        def create(self, validated_data):
            """
            当执行save方法时,自动调用。instance未传值
            :param validated_data:
            :return:
            """
            print(validated_data)
            return models.UserInfo.objects.create(**validated_data)
    
        def update(self, instance, validated_data):
            """
            当执行save方法时,自动调用。instance传值
            :param instance:
            :param validated_data:
            :return:
            """
            instance.username = validated_data.get('username', instance.username)
            instance.save()
            return instance
    3.编写serializers

     e.Serializers字段的参数

     1 read_only=False,
     2  write_only=False,
     3  required=None, 
     4 default=empty,
     5  initial=empty, 
     6 source=None,
     7  label=None,
     8  help_text=None,
     9  style=None,
    10 error_messages=None, 
    11 validators=None,
    12  allow_null=False
    View Code

    3 有关rest framework 的几点技巧

    ModelSerializer

    1、ModelSerializer 比Serializer封装好了一层,直接自己生成的create和update,不用覆盖了,其实推荐用这个,毕竟Serializer封装的很低级,既然用django,就要用好点的。

    正常的应该是这样的

    1 class AccountSerializer(serializers.ModelSerializer):
    2     class Meta:
    3         model = Account
    4         fields = ('id', 'account_name', 'users', 'created')
    5 class AccountSerializer(serializers.ModelSerializer):
    6     class Meta:
    7         model = Account
    8         fields = '__all__'
    View Code

    官网推荐用第一种,因为第二种,改变model时,可能无意会泄露数据

    3、当一个model有外键的时候,默认显示的是外键的id,此时要显示外键的所有值可以用下面,depth,会把外键的所有值显示出来

    1 class AccountSerializer(serializers.ModelSerializer):
    2     class Meta:
    3         model = Account
    4         fields = ('id', 'account_name', 'users', 'created')
    5         depth = 1
    View Code

    4、如果一个serializer中,要包含出了model以外的字段,可以

    1 class AccountSerializer(serializers.ModelSerializer):
    2     url=serializers.CharField(source='get_absolute_url',
    3 read_only=True)
    4     groups = serializers.PrimaryKeyRelatedField(many=True)
    5 
    6     class Meta:
    7         model = Account
    View Code

    外键关联信息的显示解决办法:
    几种不同的RelatedField: StringRelatedField
    PrimaryKeyRelatedField
    HyperlinkedRelatedField
    SlugRelatedField
    HyperlinkIdentityField

    不同的RelatedField ,显示的内容不同,详见官网http://www.django-rest-framework.org/api-guide/relations/

    5、把一个字段变成只读字段,需要如下操作,自增字段默认是只读的,不显式表示也是可以的

    1 class AccountSerializer(serializers.ModelSerializer):
    2     class Meta:
    3         model = Account
    4         fields = ('id', 'account_name', 'users', 'created')
    5         read_only_fields = ('account_name',)
    6 user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
    View Code

    6、把某一个字段变为只读,然后存储,通过额外字段指定。

     1 class CreateUserSerializer(serializers.ModelSerializer):
     2     class Meta:
     3         model = User
     4         fields = ('email', 'username', 'password')
     5         extra_kwargs = {'password': {'write_only': True}}
     6 
     7     def create(self, validated_data):
     8         user = User(
     9             email=validated_data['email'],
    10             username=validated_data['username']
    11         )
    12         user.set_password(validated_data['password'])
    13         user.save()
    14         return user
    View Code
    7 嵌套关系的序列化方法
     1 class TrackSerializer(serializers.ModelSerializer):
     2     class Meta:
     3         model = Track
     4         fields = ('order', 'title', 'duration')
     5 
     6 class AlbumSerializer(serializers.ModelSerializer):
     7     tracks = TrackSerializer(many=True)
     8 
     9     class Meta:
    10         model = Album
    11         fields = ('album_name', 'artist', 'tracks')
    12 
    13     def create(self, validated_data):
    14         tracks_data = validated_data.pop('tracks')
    15         album = Album.objects.create(**validated_data)
    16         for track_data in tracks_data:
    17             Track.objects.create(album=album, **track_data)
    18         return album
    View Code
  • 相关阅读:
    什么时候用到存储过程
    Group By
    李航统计学习方法(第二版)(五):k 近邻算法简介
    数据可视化之powerBI基础(十三)熟练使用Power BI的日期切片器
    数据可视化之powerBI基础(十二)PowerBI导入Excel数据有哪几种方式?
    数据可视化之powerBI基础(十一)Power BI中的数据如何导出到Excel中?
    数据可视化之powerBI基础(十)快速度量值,帮你更快的进行数据分析
    数据可视化之powerBI基础(九)Power BI中的“新表”,你会用吗?
    数据可视化之powerBI基础(八)PowerBI的表格,你真的会用吗
    数据可视化之powerBI基础(七)一文带你熟悉PowerBI建模视图中的功能
  • 原文地址:https://www.cnblogs.com/liuguniang/p/7309720.html
Copyright © 2011-2022 走看看