Day 22 drf related use

Day 22 drf related use

1. Installation

image-20201104143250581

note:After installing drf, our django will be automatically upgraded to the latest version. Students with lower versions need to change it back. Another point is that drf and django versions are compatible, so we need to find a suitable drf for our django

registered

After downloading, we need to register under the app in the setting

image-20201104200550244

Two, restful specification

REST has nothing to do with technology, it represents an architectural style (resource-oriented architecture), REST is the abbreviation of Representational State Transfer, Chinese translated as "representational state transfer"

  • Representational State Transfer: Representational State Transfer
  • The design style of the Web API interface is especially suitable for the application mode where the front and back ends are separated
  • Regardless of language and platform, any framework can write an api interface that conforms to restful specifications

Ten rules

  • **Data security: **URL links generally use https protocol for transmission

  • Interface feature performance: api keyword identification (you can see at a glance this isapi interface
    -Https: //api.baidu.com/books/
    -https: //www.baidu.com/api/books/

  • Multi-version coexistence: the interface version is identified in the url link (just like XuMulti-versionSoftware can still be used they just usedDifferent interfaces
    -https://api.baidu.com/v1/books/
    -https://api.baidu.com/v2/books/

  • Data is a resource, using nouns (plural) ***********
    -Interfaces are generally used to complete the interaction of front and back data, interactive data we call resources
    -generally recommendedPlural form of resource, Do not use verbs
    -query all books-
    https
    ://api.baidu.com/books/-https://api.baidu.com/get_all_books/ # error demonstration-
    https://api.baidu.com/delete- user # Demonstration of error-
    https://api.baidu.com/user # Example of deleting a user: Question: Is it to delete or check?

  • Resource operation is determined by the request method:

    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     - patch请求:局部修改主键为1的书
    
    https://api.baidu.com/books/1     - delete请求:删除主键为1的书
    
  • Filter, pass search conditions by uploading parameters in URL

    	https://api.example.com/v1/zoos?limit=10         :指定返回记录的数量
    
    	https://api.example.com/v1/zoos?offset=10&limit=3:指定返回记录的开始位置
    
     	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:指定筛选条件
    
  • Error message in the returned result
    -{'code':100,'msg':'Failed because of xx')

  • The returned result should meet the following specifications

    		GET /collection:返回资源对象的列表(数组)
            GET /collection/resource:返回单个资源对象(字典)
            POST /collection:返回新生成的资源对象    (新增后的对象字典)
            PUT /collection/resource:返回完整的资源对象 (修改后的对象字典)
            PATCH /collection/resource:返回完整的资源对象 (修改后的对象字典)
            DELETE /collection/resource:返回一个空文档   ()
    
  • Link address in the returned data

-查询id为1的图书接口,返回结果示例
    	{'code':100,
         'msg':'成功',
         'result':
             {'title':'superstar',
              'price':12.3,
              'publish':'https://127.0.0.1/api/v1/publish/3'
             }
        }

Three, APIview source code analysis

1. APIview的as_view

​ The closure function view of Vew is still executed internally

​ Disabled csrf

​ Everything is an object, and functions are also objects,函数地址.name = ssd

2. The closure function view in as_view in the native View class

​ Essentially executed self.dispatch(request, *args, **kwargs), the dispatch of APIView is executed

3. APIView's dispatch

def dispatch(self, request, *args, **kwargs):

        # DRF的Request类的对象,内部有request._request,是原生request

        request = self.initialize_request(request, *args, **kwargs)
        self.request = request
	try:
        self.initial(request, *args, **kwargs)
        '''
        #认证,权限,频率
        self.perform_authentication(request)
    	self.check_permissions(request)
    	self.check_throttles(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)
	# 把视图函数(类)返回的response,又包装了一下
    self.response = self.finalize_response(request, response, *args, **kwargs)
    return self.response

image-20201104172436751

Four, request analysis

1 Request类
	-request._request:原生request
    -request.data    : post请求提交的数据(urlencoded,json,formdata)
    -request.user    :不是原生的user了
    -request.query_params :原生的request.GET,为了遵循restful规范
    -requset.FILES   :新的
    -重写了__getattr__,新的request.原来所有的属性和方法,都能直接拿到
        def __getattr__(self, attr):
            return getattr(self._request, attr)

Five, serialization component introduction

1. Serialization

The serializer will convert the model object into a dictionary, and program the json string after the response

2. Deserialization

What Buckhuadan sends is data, which becomes a dictionary after request. The serializer can convert the dictionary into a model

json format data----drf: request---->Dictionary—Serializer—>Book

3. Deserialization, complete data verification function

Six, easy to use serialization group

1. Create a serialized py file

serializer.py

2. Write a class that inherits serializers.Serializer, and write the fields to be serialized in the class

from rest_framework import serializers


class BookSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=True)
    name = serializers.CharField(max_length=32, min_length=3)
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    publish = serializers.CharField(max_length=10)

3. Related

# modles.py

class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish = models.CharField(max_length=32)
# views.py

class Book(APIView):
    # get 接口 用来查询所有
    def get(self, request, *args, **kwargs):
        result = models.Book.objects.all()
        # 借助序列化器
        # 如果是多条,就是many=True
        # 如果是单个对象,就不写
        ser = serializer.BookSerializer(instance=result, many=True)
        print(type(ser))  # rest_frameword.serializers.ListSerializer
        print(ser.data)   # 得到的是一个通过序列器的字典
        
        return Response(ser.data)  # 这是使用的是自己的Response
# urls.py

    url(r'^book/', views.Book.as_view()),

Seven, serialization class field types and field parameters

Field type (the following key points)

  • IntegerField
  • CharField
  • DecimalField
  • DateTimeField
  • …So many are similar to those in models

Common field parameters

Option parameter

  • max_length maximum length
  • min_length minimum length
  • Whether allow_blank is allowed to be empty (generally not used)
  • trim_whitespace Whether to cut off white space characters (generally not equivalent to sprip)
  • max_value maximum
  • min_value minimum

General parameters

Focus

  • read_only indicates that the field is only used for serialized output, the default is False
  • write_only indicates that the field is only used for deserializing input, the default is False

grasp

  • required indicates that the field must be entered during deserialization, the default is True
  • default The default value used when deserializing
  • allow_null indicates whether the field is allowed to pass in None, the default is False

To understanding

  • validators the validators used by the field
  • error_messages A dictionary containing error numbers and error messages

8. Save function of serializer

    def post(self, request):
        print(request.data)
        # 反序列化后的数据
        ser = serializer.BookSerializer(data=request.data)
        if ser.is_valid():  # 校验数据是否可用
            ser.save()  # 保存到数据库(仅仅是save无法保存 要在序列化类中 写一个create方法)
            # 根据resful规范 返回数据 返回新生成的资源对象    (新增后的对象字典)
            return Response(ser.data)
        else:
            # 返回错误信息
            return Response(ser.errors)

Then we use postman to simulate the request

image-20201104193212767

The backend got the data but reported a create error

image-20201104193246283

image-20201104193128944

Now we implement the create method

class BookSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=False)
    name = serializers.CharField(max_length=32, min_length=3)
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    publish = serializers.CharField(max_length=10)
    
    def create(self, validated_data):
        # 创建对象  validated_data 校验后的数据
        result = models.Book.objects.create(**validated_data)
        print(result)
        return result  # 最后把结果返回

Send the request again

image-20201104193551684

There is also data in the database

image-20201104193641077

Nine, the field verification function of the serializer

We mentioned in the field parameters

validators 该字段使用的验证器Now let's use it

def length_limit(data):
    if data.startswith('xxx'):
        raise ValidationError('名字不能以xxx开头')
    else:
        return data


class BookSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=False)
    # 给名字添加 长度限制
    name = serializers.CharField(max_length=32, min_length=3, validators=[length_limit, ])
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    publish = serializers.CharField(max_length=32)
    
    def create(self, validated_data):
        # 创建对象  validated_data 校验后的数据
        result = models.Book.objects.create(**validated_data)
        print(result)
        return result  # 最后把结果返回
    
    # 局部钩子
    # z这里与form表单不同的是 局部钩子 所带的参数 就是要校验参数 不用取值
    def validate_price(self, data):
        if data > 20:
            raise ValidationError('定价过高')
        else:
            return data
    
    # 全局钩子
    # 与 form 表单用法相同
    def validate(self, attrs):
        name = attrs.get('name')
        publish = attrs.get('publish')
        if name == publish:
            raise ValidationError('书名不能和出版社同名!')
        else:
            return attrs

Let's use postman to test

image-20201104195302334

These are the three functions of the check field

  • Field’s own validation rules (max_length...)
  • validation of validators
  • 'hook'

十、read_only和write_only

read_only indicates that the field is only used for serialized output, the default is False

    id = serializers.IntegerField(required=False)
    # 给名字添加 长度限制
    name = serializers.CharField(max_length=32, min_length=3, validators=[length_limit, ], read_only=True)
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    publish = serializers.CharField(max_length=32)

So when we send and write data in the post , the name field is not written into the database, so this record is not seen in the returned data , because it isRead onlyof

image-20201104200057846

image-20201104195744566

write_only indicates that the field is only used for deserializing input, the default is False

We add to publish just write Then we can’t see this field when we get the request

    id = serializers.IntegerField(required=False)
    # 给名字添加 长度限制
    name = serializers.CharField(max_length=32, min_length=3, validators=[length_limit, ])
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    publish = serializers.CharField(max_length=32, write_only=True)

Postman simulates sending a get request, it really doesn't!

image-20201104200322294

Guess you like

Origin blog.csdn.net/A1L__/article/details/109498033