zoukankan      html  css  js  c++  java
  • 序列化和反序列化

    序列化组件:    
            1 对应着表,写序列化的类
            2 from rest_framework import serializers 
            3 写一个类,继承serializers.Serializer
            4 类中写一些属性
                -name = serializers.CharField()
            5 使用:
                -实例化产生一个对象(传参数)
                -对象.data  ---->拿到字典
            
            6 其他:
                -source:可以指定字段,也可以指定方法
                -serializers.SerializerMethodField()
                    必须要写一个方法预制对应
                    get_字段名(self,obj对象)
                        #写一些逻辑
                        #也可以用序列化的类,继续序列化别的对象
                        return ''
            7 ModelSerializer
            
            8 定义一个类
                class BookSerializer(serializers.ModelSerializer):
                    # 必须写一个内部类,名字叫Meta
                    class Meta:
                        model = Book    指定要序列化的表
                        # fields = '__all__'
                        # 指定只取这两个字段
                        fields = ['nid','name']
                        # 去掉指定的字段
                        # exclude=['publish','authors']
                        # depth = 2
            9 实例化传参数的时候,可以按关键字传:BookSerializer(instance='可以是queryset对象,也可是是单个对象',many=True/False)
            
    
                
        -HyperlinkedIdentityField(用的很少)
            -1 publish = serializers.HyperlinkedIdentityField(view_name='ttt',lookup_field='publish_id',lookup_url_kwarg='pky')
            -2 view_name:路由的别名,lookup_field:根据表的哪个字段,来拼路径,lookup_url_kwarg:反向解析有名分组的名字
            -3 写路由:url(r'^publish/(?P<pky>d+)', views.Publish.as_view(),name='ttt'),
            -4 实例化序列化类的时候,需要把request对象传过去
                book_ser=BookSerializer(ret,many=True,context={'request': request})
                
        -序列化组件的数据校验
            -类比forms组件
            -字段是否必填,通过required,来控制 authors=serializers.CharField(required=False)
            -数据校验,生成一个序列化类的对象
                -对象.is_valid()
            -新增数据:
                -对象.save()
            -修改数据:
                -在生成对象的时候,需要传instanse=查询出来的对象
                -对象.save()
        -序列化组件数据校验功能的钩子函数
            -局部
            -全局
            
        
    
        -HyperlinkedIdentityField
            -传三个参数:第一个路由名字,用来反向解析,第二个参数是要反向解析的参数值,第三个参数:有名分组的名字
            -xx=HyperlinkedIdentityField(view_name='路由名字',look_up_field='publish_id',lookup_url_kwarg='pky')
            -xx=http://127.0.0.1:8001/publish/1
        -数据校验
            -生成序列化类对象的时候,把要校验的数据(字典:前端传过来的)传过来
                -ser=BookSerializer(data=request.data)
                -ser.is_valid() 
                -显示中文:error_messages={'required': '该字段必填'}
                -局部钩子函数(value就是这个字段的值)
                    -def validate_字段名(self, value):
                        #拿到值,就可以进行判断了
                        #如果通过,把value值返回,
                        #如果不通过,抛 ValidationError 异常
                -全局钩子函数(value是验证通过的所有数据)
                    -def validate(self, value):
                        #取出数据,进行判断
                        #如果通过,把value值返回,
                        #如果不通过,抛 ValidationError 异常
        -保存和更新:(必须继承ModelSerializer)
            -保存
                -ser=BookSerializer(data=request.data)
                -ser.save()---->向数据库中插一条数据
            -更新
                -ser=BookSerializer(data=request.data.instance='要更新的对象')
                -ser.save()---->向数据库中插一条数据
    总结
    from rest_framework import serializers
    
    from app01 import models
    
    
    class AuthorSerializer(serializers.Serializer):
        nid = serializers.CharField()
        name = serializers.CharField()
        age = serializers.CharField()
    
    
    # class BookSerializer(serializers.Serializer):
    #     name = serializers.CharField()
    #     # publish = serializers.CharField()
    #     publish = serializers.HyperlinkedIdentityField(view_name='ttt',lookup_field='publish_id',lookup_url_kwarg='pky')
    from rest_framework.exceptions import ValidationError
    
    
    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Book
            fields = '__all__'
    
        name = serializers.CharField(min_length=2, error_messages={'required': '该字段必填'})
        authors = serializers.CharField(required=False)
    
        # 局部钩子:
        def validate_name(self, value):
            # print(value)
            if value.startswith('sb'):
                # 不能以sb开头
                raise ValidationError('不能以sb开头')
            else:
                return value
    
        # 全局钩子找到了
        def validate(self, value):
            # value是所有校验通过数据的字典
            print(value)
            name = value.get('name')
            price = value.get('price')
            if name and price:
                if str(name) == str(price):
                    return value
                else:
                    raise ValidationError('名字跟价格不相等')
            return value
    mySer.py
    """day97 URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/1.11/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.conf.urls import url, include
        2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
    """
    from django.conf.urls import url
    from django.contrib import admin
    
    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^books/$', views.Books.as_view()),
        url(r'^books/(?P<pk>d+)', views.BooksDetail.as_view()),
        url(r'^publish/(?P<pky>d+)', views.Publish.as_view(),name='ttt'),
        url(r'^login/', views.Login.as_view()),
    ]
    urls.py
    from django.shortcuts import render, HttpResponse
    from app01.mySer import BookSerializer
    from django.http import JsonResponse
    from app01 import models
    # Create your views here.
    from rest_framework.views import APIView
    
    
    class Books(APIView):
        def get(self, request, *args, **kwargs):
            ret = models.Book.objects.all()
            # 生成一个序列化的对象,传参数
            # 序列化多条,记住many=True
            book_ser = BookSerializer(ret, many=True, context={'request': request})
            print(book_ser.data)
            return JsonResponse(book_ser.data, safe=False)
    
        def post(self, request, *args, **kwargs):
            # 前端传递过来的数据从data中取
            # 用序列化类的数据校验
            # data参数,是要校验的数据
            response = {'status': 100, 'msg': '成功'}
            ser = BookSerializer(data=request.data)
            if ser.is_valid():
                # 如果数据校验通过,is_valid是True
                # 保存到数据库,ser是谁的对象?继承了ModelSerializer的类的对象
                ser.save()
            else:
                response['status'] = 101
                response['msg'] = ser.errors
            return JsonResponse(response, safe=False)
    
    from rest_framework import exceptions
    class Auth():
        def authenticate(self, request):
            # 包装后的request对象,请求来的所有东西都能拿出来
            # 如果认证通过,需要返回东西,如果认证不通过,要抛异常
            token=request.GET.get('token')
            ret=models.UserToken.objects.filter(token=token).first()
            #如果有值,说明登录过了,而且带的随机字符串也是正确的
            if ret:
                return None
            else:
                # 如果没有值,抛异常
                raise exceptions.APIException('您没有登录')
    
    
    from rest_framework.request import Request
    
    
    class BooksDetail(APIView):
        authentication_classes = [Auth, ]
    
        def get(self, request, pk):
            response = {'status': 100, 'msg': '成功'}
            ret = models.Book.objects.all().filter(pk=pk).first()
            # 生成一个序列化的对象,传参数
            # 序列化单,记住many=False
            if ret:
                book_ser = BookSerializer(ret, many=False)
                print(book_ser.data)
                response['data'] = book_ser.data
            else:
                response['status'] = 101
                response['msg'] = '您查询的不存在'
    
            return JsonResponse(response, safe=False)
    
        def put(self, request, pk):
            response = {'status': 100, 'msg': '成功'}
            ret = models.Book.objects.all().filter(pk=pk).first()
            if ret:
                # 数据校验
                # 传instance和不传instance,传instance的区别
                # 不传instance,调save(),往数据库新增数据
                # 传instance,调save(),修改数据
                ser = BookSerializer(data=request.data, instance=ret)
                if ser.is_valid():
                    # ret.name=request.data.get('name')
                    ser.save()
                else:
                    response['status'] = 101
                    response['msg'] = ser.errors
            else:
                response['status'] = 102
                response['msg'] = '修改的对象不存在'
            return JsonResponse(response, safe=False)
    
    
    class Publish(APIView):
        def get(self, request, *args, **kwargs):
            return HttpResponse('ok')
    
    import uuid
    class Login(APIView):
        def post(self, request):
            response={'status':100,'msg':'登录成功'}
            name = request.data.get('name')
            pwd = request.data.get('pwd')
            user = models.UserInfo.objects.filter(name=name, pwd=pwd).first()
            if not user:
                response['status']=101
                response['msg']='用户名或密码错误'
            else:
                # 生成一个随机字符串
                token=uuid.uuid4()
                # 去数据库保存
                models.UserToken.objects.create(token=token,user=user)
                response['token']=token
            return JsonResponse(response,safe=False)
    views.py
    from django.db import models
    
    # Create your models here.
    from django.db import models
    
    
    # Create your models here.
    
    class Book(models.Model):
        nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=5, decimal_places=2)
        publish_date = models.DateField()
    
        publish = models.ForeignKey(to='Publish', to_field='nid', on_delete=models.CASCADE)
        authors = models.ManyToManyField(to='Author')
    
        def __str__(self):
            return self.name
    
    
    class Author(models.Model):
        nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        age = models.IntegerField()
        author_detail = models.OneToOneField(to='AuthorDatail', to_field='nid', unique=True, on_delete=models.CASCADE)
    
    
    class AuthorDatail(models.Model):
        nid = models.AutoField(primary_key=True)
        telephone = models.BigIntegerField()
        birthday = models.DateField()
        addr = models.CharField(max_length=64)
    
    
    class Publish(models.Model):
        nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        city = models.CharField(max_length=32)
        email = models.EmailField()
    
        def __str__(self):
            return self.name
    
        def test(self):
            return self.email
    
    
    class UserInfo(models.Model):
        name = models.CharField(max_length=32)
        pwd = models.CharField(max_length=32)
    
    
    class UserToken(models.Model):
        token = models.CharField(max_length=64)
        user = models.OneToOneField(to=UserInfo)
    models.py
  • 相关阅读:
    2010年8月26日周四_understanding ArcGIS Server_overview_8.1
    2010年8月23日周一_FeatureLayer_6.13
    2010年8月22日周日_StylingAndSkinningScaleBar_6.12
    2010年8月26日周四_underStanding Flex_FlexComponets_7.4
    Flex组件的项目渲染器(ItemRenderer)使用总结
    2010年8月26日周四_understanding Flex_componentsLifeCycle_7.5
    2010年8月26日周四_understanding Flex_MXML and ActionScript_7.2
    缺页中断
    后缀式
    lua continue
  • 原文地址:https://www.cnblogs.com/xuqidong/p/13769426.html
Copyright © 2011-2022 走看看