zoukankan      html  css  js  c++  java
  • django 之(一) --- DjangoRestFormwork

    接口概念

      IOP:面向接口编程,不再关注具体的实现;只关注输入、输出。

      http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html

    服务器返回数据类型:

      网页数据html,为浏览器使用

      Json数据,ajax javascript发请求的一种方式;也可以使用request的python请求方式

    为移动端编写接口关注:

      接口地址是什么:/xxx/yyy/zzz

      接口需要什么参数:参数根据业务场景

      返回什么格式的数据:大多数是json数据  

    RestfulAPI:

        一种软件架构风格、设计风格、而不是标准,只是提供了一组设计原则和约束条件。它主要用户客户端和服务器交互类的软件。

      基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存机制等。REST全程是Representational State Transfer,表征性状态转移。

      首次在2000年Roy Thomas Fielding的博士论文中出现,Fielding是一个非常重要的人,他是HTTP协议(1.0版和1.1版)的主要设计者,

      Apache服务器软件的作者之一,Apache基金会的第一任主席。所以,他的这篇论文一经发表,就引起了广泛的关注。

    理解Rest-Formwork

    介绍:https://github.com/RockTeach/PythonCourse/blob/master/web/flask/restful.md

      要理解RESTful架构,最好的就是去理解它的单词 Representational State Transfer 到底是什么意思,它的每一个词到底要表达什么。

      REST的释义,"(资源的)表现层状态转化",其实这省略了主语。“表现层”其实指的是“资源(Resource)”的“表现层”。

    状态码

      服务器向用户返回的状态码和提示信息,常见的有以下一些地方

    • 200:OK - [GET]:服务器成功返回用户请求的数据
    • 201:CREATED -[POST/PUT/PATCH]:用户新建或修改数据成功
    • 202:Accepted - [*] :表示一个请求已经进入后台排队(异步任务)
    • 204:NO CONTENT - [DELETE]:表示数据删除成功
    • 400:INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误
    • 401:Unauthorized - [*] :表示用户没有权限(令牌,用户名,密码错误)
    • 403:Forbidden - [*]:表示用户得到授权,但是访问是被禁止的
    • 404:NOT FOUND - [*]:用户发出的请求针对的是不存在的记录
    • 406:Not Acceptable - [*]:用户请求格式不可得
    • 410:Gone - [GET] :用户请求的资源被永久移除,且不会再得到的
    • 422:Unprocesable entity -[POST/PUT/PATCH]:当创建一个对象时,发生一个验证错误
    • 500:INTERNAL SERVER EROR - [*] :服务器内部发生错误

    资源(Resource)

      所谓“资源”,就是网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本,一张图片,一首歌曲,一种服务,总之就是一个具体的实例。

      你可以使用一个URI(统一资源定位符)指向它,每种资源对应一个特定的URI。要获取这个资源,访问它的URI就可以了,因此URI就成了每一个资源的地址或独一无二的识别符。

      所谓“上网”就是与互联网上一系列的“资源”互动,调用它们的URI。

    表现层(Representation)

      “资源”是一种信息实体,它可以有多种外在表现形式。我们把“资源”具体呈现出来的形式,叫做它的”表现层“(Representation)。

      URI只代表资源的实体,不代表它的形式。严格地说,有些网站最后的”.html“后缀名是不必要的,因为这个后缀表示格式,属于”表现层“范畴,而URI应该只代表”资源“的位置。

      它的具体表现形式,应该在HTTP请求头的信息中使用Accept和Content-Type字段指定。

    状态转换(State Transfer)

      访问一个网站,就代表客户端和服务端的一个互动过程。在这个过程中,势必涉及到数据和状态的变化。

      互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务端。

      因此,如果客户端想要操作服务器,就必须通过某种手段,让服务器端发生”状态转换(State Transfer)“。

      而这种转换是建立在表现层之上的,所以就是”表现层状态转化“。

      客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议中,四个表示操作方式的动词:GET,POST,PUT,DELETE。

      它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可用于更新资源),PUT用来更新资源,DELETE用来删除资源

    总结 :

    1. 每一个URI代表一种资源
    2. 客户端和服务器之间,传递这种资源的某种表现层
    3. 客户端通过四个HTTP动词,对服务端资源进行操作,实现”表现层状态转换“
    4. 同一个url针对用户的不同的请求操作,表现出来的状态是不同的。表现出来的多种形式,就是表现层状态转换。
    • RESTful是软件架构设计思想。使用在CS,客户端和服务端这种架构模型中。

    • 表现层状态转换

      • 主语 (资源)

      • URI 每个URI代表一种资源

      • 资源展现给我们的形式就叫做表现层

      • 通过HTTP的请求谓词来实现表现层转换

    • 重要概念

      • URI、HTTP请求谓词、JSON

    注意:

      postman/前端 在向服务器提交json数据时,需要声明提交的类型。

      在postman的请求的headers增加content-type:application/json。

      flask 在确认请求数据是通过json提交后,会将json字符产转换成 字典。保存在request.json中

      函数视图:FBV(function base views);  类视图:CBV(class base views)

    图示:

    • 前后端统一开发

        

    • 前后端分离开发

        


    FBV简单体验:由源码中的dispatch进行各请求分发

    • api/urls.py
    1 from django.conf.urls import url
    2 from API import views
    3 
    4 urlpatterns = [
    5     url(r'^books/$', views.books, name='books'),
    6     url(r'^books/(?P<bookid>d+)/', views.book, name='book'),
    7
    • api/models.py 
    1 from django.db import models
    2 
    3 class Book(models.Model):
    4     b_name = models.CharField(max_length=32)
    5     b_price = models.FloatField(default=1)
    6 
    7     def to_dict(self):
    8         return {'id': self.id, 'b_name': self.b_name, 'b_price': self.b_price}
    • api/views.py  [选中此文件,右键--> Refactor-->Convert To Python Package 将其变成一个包文件] [from .BookModel import Book 导入到在此包文件中的init.py文件]
     1 from django.http import JsonResponse
     2 from django.views.decorators.csrf import csrf_exempt
     3 from API.models import Book
     4 
     6 @csrf_exempt  # 进行csrf豁免
     7 def books(request):
     8     # get 获取书
     9     if request.method == "GET":
    10         book_list = Book.objects.all()
    11         book_list_json = []
    12         for book in book_list:
    13             book_list_json.append(book.to_dict())
    14         data = {
    15             'status': 200,
    16             'msg': 'ok',
    17             'data': book_list_json
    18         }
    19         return JsonResponse(data=data)
    20     # post 创建书
    21     elif request.method == "POST":
    22         b_name = request.POST.get('b_name')
    23         b_price = request.POST.get('b_price')
    24         book = Book()
    25         book.b_name = b_name
    26         book.b_price = b_price
    27         book.save()
    28         data = {
    29             'status': 201,
    30             'msg': 'add success',
    31             'data': book.to_dict()
    32         }
    33         return JsonResponse(data=data, status=201)
    34 
    35 # 注意: 在pycahrm工具栏:Tools ---> HTTP Client ---> Test RESTful web server 进行模拟请求。亦可HTTPie和Postman
    36 
    37 @csrf_exempt
    38 def book(request, bookid):
    39     # get  带参数获取某一本书
    40     if request.method == "GET":
    41         book_obj = Book.objects.get(pk=bookid)
    42         data = {
    43             'msg': 'ok',
    44             'status': 200,
    45             'data': book_obj.to_dict()
    46         }
    47         return JsonResponse(data=data)
    48     # delete 带参数删除某一个书
    49     elif request.method == "DELETE":
    50         book_obj = Book.objects.get(pk=bookid)
    51         book_obj.delete()
    52         data = {
    53             'msg': 'delete success',
    54             'status': 204,  # 前端看到的状态码
    55             # 'data': {} 如果某个对象删除后没有数据了,有默认值就返回对应的数据类型格式,否则前端不知如何解析
    56         }
    57         return JsonResponse(data=data, # status=204) # status=204 设置真正的网络传输状态码204,舍弃响应体中的内容
    58     
    • books.html
     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>BookList</title>
     6     <script type="text/javascript" src="/static/js/jquery.js"></script>
     7     <script type="text/javascript">
     8         $(function () {
     9            // $("button").click(function () {
    10                 $.getJSON("/api/books/", function (data) {
    11                     console.log(data);
    12                     if (data['status'] === 200){
    13                         var $ul = $("ul");
    14                         var books = data['data'];
    15                         for(var i=0; i < books.length; i++){
    16                             var $li = $("<li></li>");
    17                             $li.html(books[i]['b_name']);
    18                             $li.appendTo($ul);
    19                         }
    20                     }
    21                 })
    22           //  })
    23         })
    24 
    25     </script>
    26 </head>

    CBV简单体验:由源码中的dispatch进行各请求分发

    •  urls.py
    from django.contrib import admin
    from django.urls import path
    from user.views import UserView, RegisterView
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('register/', RegisterView.as_view(), name='register'),
        path('user/<int:uid>', UserView.as_view(), name='user'),
    ]
    • views.py
     1 # Create your views here.
     2 from django.http import HttpResponse
     3 from django.views import View
     5 
     6 #FBV
     7 def indexs(request):
     8     return HttpResponse('基础流程')
    10 
    11 #CRF: 实现登陆注册
    12 class RegisterView(View):
    13     # 用户登陆
    14     def get(self, request):
    15         pass
    16     # 用户注册
    17     def post(self, request):
    18         pass
    19 
    20 #CRF: get post put patch  delete
    21 class UserView(View):
    22     # 请求get,获取信息
    23     def get(self, request, uid):
    24         pass
    25     # 提交post,添加信息
    26     def post(self, request, uid):
    27         pass
    28     # 修改put,全部修改
    29     def put(self, request, uid):
    30         pass
    31     # 修改patch,差量修改
    32     def patch(self, request, uid):
    33         pass
    34     # 删除delete,删除操作
    35     def delete(self, request, uid):
    36         pass

    使用:

    •  urls.py  只能接收已经存在的属性作为参数
    1 from django.conf.urls import url
    2 from CBV import views
    3 
    4 urlpatterns = [
    5     url(r'^hello/', views.HelloCBV.as_view(msg='Sleeping'), name='hello'),
        # as_view(msg)中的参数msg(变量名),只能接收此路由对应的类视图中已经存在的属性作为参数
    6 ]
    • views.py
     1 from django.http import HttpResponse
     2 from django.views import View
     3 
     4 class HelloCBV(View):
     5 
     6     msg = None # 类视图中只有设置了此msg属性,路由中as_view(msg)中的变量名msg才能接收到并生效(名字要对应好)
     7     def get(self, request):
     8         return HttpResponse("hahaha %s" % self.msg)
     9     def post(self, request):
    10         return HttpResponse("POST 666")
    11     def put(self, request):
    12         return HttpResponse("PUT 666")

    Api接口 CBV方式 利用在模型中定义[对象转字典]的类方法 来简单实现

    •  urls.py
    from django.contrib import admin
    from django.urls import path
    from user.views import UserView
    
    urlpatterns = [
        path('user/<int:uid>', UserView.as_view(), name='user'),
    ]
    • models.py
     1 from django.db import models
     2 
     3 class User(models.Model):
     4     username = models.CharField(max_length=20, unique=True, verbose_name='用户名')
     5     password = models.CharField(max_length=128, verbose_name='密码')
     6 
     7     class Meta:
     8         db_table = 'user'
     9         verbose_name = '用户表'
    10         verbose_name_plural = verbose_name
    11 
    12     def __str__(self):
    13         return self.username
    15     def to_dict(self): # 在模型中定义类方法,实现模型对象的序列化,转为字典形式
    16         return {'id': self.id, 'username': self.username, 'password': self.password}
    • views.py
     1 from django.http import JsonResponse
     2 from django.views import View
     3 from user.models import User
     4 
     5 class UserView(View):
     6     def get(self, request, uid):
     7         user = User.objects.get(pk=uid)
     8         return JsonResponse({'status': 200, 'user': user.to_dict()}) 
           # 在模型中定义类方法,实现模型对象的序列化,转为字典形式
    10 def post(self, request, uid): 11 username = request.POST.get('username') 12 password = request.POST.get('password') 13 repassword = request.POST.get('repassword') 14 if password == repassword: 15 user = User.objects.create(username=username, password=password) 16 if user: 17 return JsonResponse({'status': 200, 'msg': '注册成功'}) 18 return JsonResponse({'status': 200, 'msg': '注册失败'})


    Django-Rest-Formwork

    安装配置

    • pip install djangorestframework 若使用序列化和类视图继承view或APIView,必须安装此行
    • 添加:INSTALLED_APPS = ['user.apps.UserConfig',  'rest_framework', ]在settings.py文件中

            

    初步体验:

    • urls.py  请求:某个http://127.0.0.1:8000/groups/2/ 或 某组http://127.0.0.1:8000/groups
     1 from django.conf.urls import url, include
     2 from rest_framework.routers import DefaultRouter
     3 from drf.views import UserViewSet, GroupViewSet
     4 
     5 # router做了路由注册
     6 router = DefaultRouter()
     7 router.register(r'users',UserViewSet)
     8 router.register(r'groups',GroupViewSet)
     9 
    10 urlpatterns = [
    11    url(r'^',include(router.urls)),
    12 ]
    • drf/serializers.py
     1 from django.contrib.auth.models import User, Group
     2 from rest_framework import serializers
     3 
     4 # HyperlinkedModelSerializer 实现超链接
     5 class UserSerializer(serializers.HyperlinkedModelSerializer):
     6     class Meta:
     7         model = User  # 系统自带的user
     8         fields = ('url', 'username', 'email', 'groups')
     9 # HyperlinkedModelSerializer 实现超链接
    10 class GroupSerializer(serializers.HyperlinkedModelSerializer):
    11     class Meta:
    12         model = Group  # 系统自带的group
    13         fields = ('url', 'name')
    • drf/views.py
     1 from django.contrib.auth.models import User, Group
     2 from rest_framework import viewsets
     3 from drf.serializers import UserSerializer, GroupSerializer
     4 
     5 # 继承自:viewsets.ModelViewSet。对数据集合实现了:get、post
     6 # 本身是一个CBV,也是一个视图集合。 对单个集合实现了:get、post、delete、put、patch封装
     7 class UserViewSet(viewsets.ModelViewSet):
     8     queryset = User.objects.all()
     9     serializer_class = UserSerializer
    10 
    11 # 继承自:viewsets.ModelViewSet。对数据集合实现了:get、post
    12 # 本身是一个CBV,也是一个视图集合。 对单个集合实现了:get、post、delete、put、patch封装
    13 class GroupViewSet(viewsets.ModelViewSet):
    14     queryset = Group.objects.all()
    15     serializer_class = GroupSerializer

     注意:一般不会用这种继承方式,不灵活


     序列化器 

    • 序列化:   表示将对象转换成可以在IO[网络]中传输的格式如json
    • 反序列化:将在IO[网络]中传输的格式[如json]转化为对象的形式。

    基本使用1:

    • urls.py
    1 from django.conf.urls import url, include
    2 
    3 urlpatterns = [
    4     url(r'^ser/', include('RestSerializers.urls')),
    5 ]
    • RestSerializers/urls.py
    1 from django.conf.urls import url
    2 from RestSerializers import views
    3 
    4 urlpatterns = [
    5     url(r'^persons/', views.PersonView.as_view()),
    6     url(r'^students/', views.StudentView.as_view()),
    7     url(r'^books/', views.books), # FBV
    8 ]
    • RestSerializers/models.py
     1 from django.db import models
     2 
     3 
     4 class Person(models.Model):
     5     p_name = models.CharField(max_length=32)
     6     p_age = models.IntegerField(default=1)
     7     p_sex = models.BooleanField(default=False)
     8 
     9 
    10 class Student(models.Model):
    11     s_name = models.CharField(max_length=32)
    12     s_age = models.IntegerField(default=1)
    • RestSerializers/serializers.py
     1 from rest_framework import serializers
     2 from RestSerializers.models import Person, Student, Book
     3 
     4 # serialization的子类
     5 """
     6 模块serializers中
     7     1。Serializer:     手动原生序列化。有创建和更新两个功能    
     9     2。ModelSerializer:模型序列化。     
    11     3。HyperLinkedModelSerializer:带超链接的模型序列化工具
    12 """
    13 class PersonSerializer(serializers.Serializer):
        # 手动设置需要序列还的字段
    14 id = serializers.IntegerField(read_only=True) 15 p_name = serializers.CharField(max_length=32) 16 p_age = serializers.IntegerField(default=1) 17 p_sex = serializers.BooleanField(default=False) 18 19 # 实现抽象方法,手动创建对象。validated_data验证过的数据 20 def create(self, validated_data): 21 return Person.objects.create(**validated_data) 22 23 # 实现抽象方法,手动更新对象。validated_data验证过的数据,instance实例 24 def update(self, instance, validated_data): 25 instance.p_name = validated_data.get('p_name', instance.p_name) # 没有获取到,给其原有值 26 instance.p_age = validated_data.get('p_age', instance.p_age) 27 instance.p_sex = validated_data.get('p_sex', instance.p_sex) 28 instance.save() 29 return instance 30 31 32 class StudentSerializer(serializers.ModelSerializer): 33 class Meta: 34 model = Student 35 fields = ('s_name', 's_age')
           # fields:包含什么字段;exclude:不包含什么字段
    • RestSerializers/views.py
     1 from django.http import JsonResponse
     2 from django.views import View
     3 from rest_framework import status
     4 from rest_framework.decorators import api_view
     5 from rest_framework.response import Response
     6 from rest_framework.views import APIView
     7 from RestSerializers.models import Person, Student
     8 from RestSerializers.serializers import PersonSerializer, StudentSerializer, 
     9 
    10 
    11 class PersonView(View):
    12 
    13     def get(self, request):
    14         persons = Person.objects.all()
    15         # many=True 表示有多个需要序列化转化
    16         person_serializer = PersonSerializer(persons, many=True)
    17         return JsonResponse(person_serializer.data, safe=False)
    18 
    19     def post(self, request):
    20         p_name = request.POST.get("p_name")
    21         p_age = request.POST.get("p_age")
    22         person = Person()
    23         person.p_name = p_name
    24         person.p_age = p_age
    25         person.save()
    26         person_serializer = PersonSerializer(person)
    27         return JsonResponse(person_serializer.data)
    28 
    29 
    30 class StudentView(APIView):
    31 
    32     def post(self, request):
    33         s_name = request.POST.get('s_name')
    34         s_age = request.POST.get('s_age')
    35         student = Student()
    36         student.s_name = s_name
    37         student.s_age = s_age
    38         student.save()
    39         student_serializer = StudentSerializer(student)
    40         # 只要类视图继承自APIView,request类型就变成了<class 'rest_framework.request.Request'>
    41         print(type(request))
    42         return JsonResponse(student_serializer.data

     基本使用2:

    • urls.py
    1 from django.contrib import admin
    2 from django.urls import path
    3 from user import views
    4 
    5 urlpatterns = [
    6     path('admin/', admin.site.urls),
    7     path('oneuser/', views.UserViews.as_view(), name='user'),
    8     path('twouser/', views.UserViewsSimple.as_view(), name='user'),
    9 ]
    • user/models.py
     1 from django.db import models
     2 
     3 class User(models.Model):
     4     username = models.CharField(max_length=20, unique=True)
     5     password = models.CharField(max_length=128)
     6     phone = models.CharField(max_length=11)
     7     add_time = models.DateTimeField(auto_now=True)
     8 
     9     class Meta:
    10         db_table = 'user'  # 数据库中此模型的表名称
    11 
    12     def __str__(self):
    13         return self.username
    • user/serializers.py  在此文件内构件序列化类。继承自serializers.Serializer 和 继承自serializers.ModelSerializer
     1 from django.contrib.auth.hashers import make_password
     2 from rest_framework import serializers
     3 from user.models import User
     4 
     5 # UserSerializer class中的第一部分定义了有哪些字段需要被序列化/反序列化。
     6 # 方法create()和方法update()部分定义了当调用serializer.save()方法时,serializer应该怎样构造实例
     7 
     8 # 基础写法。建序列化类,继承自serializers.Serializer
     9 class UserSerializer(serializers.Serializer):
    10     id = serializers.IntegerField(read_only=True)                    # read_only=True 只读,不可修改
    11     username = serializers.CharField(max_length=20, min_length=6, required=True)  # required=True 必填项
    12     password = serializers.CharField(max_length=128, required=True)  # max_lenth = 128 最长是128
    13     phone = serializers.CharField(max_length=11, min_length=11)      # min_lenth = 11 最短是11
    
    # -------------------------------------------------------------------------------------------------------#
    15 # UserSerializerSimple继承自ModelSerializer; 16 # ModelSerializer继承自Serializer;ModelSerializer中重写了BaseSerializer父类中的create()方法 17 # Serializer继承自BaseSerializer。 18 # BaseSerializer有save()方法和create()方法。所以UserSerializerSimple就可以调用save()方法 19 20 # 简化写法。建序列化类,继承自serializers.ModelSerializer 21 class UserSerializerSimple(serializers.ModelSerializer): 22 # 新增需要验证的字段,且数据库中没有此字段。需要write_only=True表示只是在前端验证,不会进到模型中去 23 repassword = serializers.CharField(max_length=128, write_only=True) 24 25 class Meta: 26 model = User 27 # fields = '__all__' 对所有字段进行校验 28 # exclude = ('id') 排除不想校验的字段 29 fields = ['id', 'username', 'password', 'phone','repassword'] # 需要序列化的字段有哪些 30 31 # 重写父类方法 验证密码一致。重写父类中的validate进行全局验证。
        # attrs是传递来的所有参数的字典形式。如果只验证一个参数,如验证密码长度可以直接把password当作参数
    32 def validate(self, attrs): 33 if attrs['password'] != attrs['repassword']: 34 raise serializers.ValidationError('两次密码不相等') 35 return attrs 36 37 # 重写父类方法 实现密码加密。重写父类中的create方法。validated_data是 38 def create(self, validated_data): 39 username = validated_data['username'] # validated_data父类中的 40 password = validated_data['password'] 41 phone = validated_data['phone'] 42 password = make_password(password) # 密码加密 43 user = User.objects.create(username=username, password=password, phone=phone) 44 45 return user
    • user/views.py
     1 from django.contrib.auth.hashers import make_password
     2 from django.http import JsonResponse
     3 from rest_framework.views import APIView
     4 from user.models import User
     5 from user.serializers import UserSerializer, UserSerializerSimple
     6 
     7 
     8 # 基本实现 序列化
     9 class UserViews(APIView):  # APIView是View的子类
    10     # get请求
    11     def get(self, request):
    12         pass
    13 
    14     # post请求 用户注册。http://127.0.0.1:8000/oneuser/
    15     def post(self, request):
    16         username = request.POST.get('username')
    17         password = request.POST.get('password')
    18         phone = request.POST.get('phone')
    19 
    20         password = make_password(password)  # 密码加密
    21         # 1。创建并得到一个用户对象
    22         user = User.objects.create(username=username, password=password, phone=phone)
    23         # 2。放到UserSerializer类中得到一个用户序列化对象。
    24         user_serializer = UserSerializer(user)
    25         # 3。将序列化的数据(json)返回出去。获取序列化中的数据的方法是:序列化类对象名.data(得到序列化之后的数据,打印是字典类型)
    26         return JsonResponse({'status': 200, 'user': user_serializer.data})

    #----------------------------------------------------------------------------------------------------------------#

    29 # 简化实现 序列化 30 class UserViewsSimple(APIView): # APIView是View的子类 31 # get请求 32 def get(self, request): 33 pass 34 # post请求 用户注册。http://127.0.0.1:8000/twouser/ 35 def post(self, request): 36 # 1。将前端传递的数据送到Serializer中验证,获取序列化对象。只有在继承自APIView中的子类才可以使用request.data 37 user_serializer = UserSerializerSimple(data=request.data) 38 # 2。# 判断前端传来的数据时候是否符合models.py中定义的数据格式要求 39 if user_serializer.is_valid(): 40 user_serializer.save() 41 return JsonResponse({'status': 200, 'user': user_serializer.data}) 42 return JsonResponse({'status':400})

    总结:

    方法:

    • user_serializer.is_valid( )
      • 序列化类对象.is_valid() :此方法功能是判断传入的数据是否符合models中定义的数据格式要求 
    • user_serializer.data
      • 序列化类对象.data :此方法功能是 将序列化后的数据获取出来
    • user_serializer.save()
      • 序列化类对象.save() : 此方法功能是 将验证通过的数据存到数据库中 
      • user_serializer.save() 底层save()两个动作create,update

    • request.data
      • request.data :此方法功能是 获取前端传递来的所有数据。只有类视图继承自APIView父类,才会有此方法
      • data = JSONParser().parse(request)

    注意:

    • ModelSerializer需要解决的两个问题:
      • 某个字段不属于指定model,它是write_only,需要用户传进来,但我们不能对它进行save( ),因为ModelSerializer是基于Model,这个字段在Model中没有对应属性字段,这个时候我们需要重载validate!write_only与read_only对应。就是用户post过来的数据,后台服务器处理后不会再经过序列化后返回给客户端;最常见的就是我们在使用手机注册的验证码和填写的密码。required: 顾名思义,就是这个字段是否必填,例如要求:用户名,密码等是必须填写的;不填写就直接报错
allow_null/allow_blank:是否允许为NULL/空 。 
error_messages:出错时,信息提示。
      • 某个字段属于指定model,它是read_only,read_only:True表示不允许用户自己上传,只能用于api的输出。如果某个字段设置了read_only=True,那么就不需要进行数据验证,只会在返回时,将这个字段序列化后返回,举个简单的例子:在用户进行购物的时候,用户post订单时,肯定会产生一个订单号,而这个订单号应该由后台逻辑完成,而不应该由用户post过来,如果不设置read_only=True,那么验证的时候就会报错。再例如,我们在网上购物时,支付时通常会产生支付状态,交易号,订单号,支付时间等字段,这些字段都应该设置为read_only=True,即这些字段都应该由后台产生然后返回给客户端;
      • write_only:前端必须传递过来,但是序列化时不被序列化
      • read_only: 前端必须传递过来,但是序列化的时候会自动给出

    补充:

    • 新建的app包文件,需要调用models.py,生成迁移文件时,必须要将app包文件注册到settings.py文件中。
    • 如果只是调用路由和视图函数文件,不需要models文件时,不注册新建的app包文件在settings.py也没关系

     

    生如逆旅 一苇以航
  • 相关阅读:
    js 注意
    JS学习大作业-Excel
    js继承
    转载:margin外边距合并问题以及解决方式
    CSS属性选择器和部分伪类
    HTML使用CSS样式的方法
    link元素 rel src href属性
    【2020.01.06】SDN大作业
    【2019.12.11】SDN上机第7次作业
    【2019.12.04】SDN上机第6次作业
  • 原文地址:https://www.cnblogs.com/TMMM/p/11796979.html
Copyright © 2011-2022 走看看