• Django 之restfromwork 序列化组件实现数据增删查改


    rest-framework序列化之Serializer

    models.py

    from django.db import models
    
    # Create your models here.
    
    
    class Book(models.Model):
        title=models.CharField(max_length=32)
        price=models.IntegerField()
        pub_date=models.DateField()
        publish=models.ForeignKey("Publish")
        authors=models.ManyToManyField("Author")
        def __str__(self):
            return self.title
    
    class Publish(models.Model):
        name=models.CharField(max_length=32)
        email=models.EmailField()
        def __str__(self):
            return self.name
    
    class Author(models.Model):
        name=models.CharField(max_length=32)
        age=models.IntegerField()
        def __str__(self):
            return self.name
    

    view部分:

    from rest_framework.views import APIView
    from rest_framework.response import Response
    from .models import *
    from django.shortcuts import HttpResponse
    from django.core import serializers  # django 自带的序列化组件
    
    
    from rest_framework import serializers
    
    class BookSerializers(serializers.Serializer):
        title=serializers.CharField(max_length=32)
        price=serializers.IntegerField()
        pub_date=serializers.DateField()
        publish=serializers.CharField(source="publish.name")
        #authors=serializers.CharField(source="authors.all")
        authors=serializers.SerializerMethodField()
        def get_authors(self,obj):
            temp=[]
            for author in obj.authors.all():
                temp.append(author.name)
            return temp
      #此处可以继续用author的Serializers,
      # def get_authors(self,obj):
        #     ret=obj.authors.all()
        #     ss=AuthorSerializer(ret,many=True)
        #     return ss.data
    
    class BookViewSet(APIView):
    
        def get(self,request,*args,**kwargs):
            book_list=Book.objects.all()
            # 序列化方式1:
            # from django.forms.models import model_to_dict
            # import json
            # data=[]
            # for obj in book_list:
            #     data.append(model_to_dict(obj))
            # print(data)
            # return HttpResponse("ok")
    
            # 序列化方式2:
            # data=serializers.serialize("json",book_list)
            # return HttpResponse(data)
    
            # 序列化方式3:
            bs=BookSerializers(book_list,many=True)     #many=True代表有多条数据,如果只有一条数据,many=False
            return Response(bs.data)
         # 序列化方式4: 
          # ret=models.Book.objects.all().values('nid','title')
         # dd=list(ret)
            # return HttpResponse(json.dumps(dd))
    
    
    

    注意:

    ​ source 如果是字段,会显示字段,如果是方法,会执行方法,不用加括号(authors=serializers.CharField(source='authors.all'))

    ​ 如在模型中定义一个方法,直接可以在在source指定执行

    class UserInfo(models.Model):
        user_type_choices = (
            (1,'普通用户'),
            (2,'VIP'),
            (3,'SVIP'),
        )
        user_type = models.IntegerField(choices=user_type_choices)
    
        username = models.CharField(max_length=32,unique=True)
        password = models.CharField(max_length=64)
    
    
    #视图
    ret=models.UserInfo.objects.filter(pk=1).first()
    aa=ret.get_user_type_display()
    
    #serializer
    xx=serializers.CharField(source='get_user_type_display')
    

    rest-framework序列化之ModelSerializer

    urls.py

    """
    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/(?P<id>d*)',views.Book.as_view())
    ]
    

    models.py

    from django.db import models
    
    
    # Create your models here.
    
    
    class Book(models.Model):
        title = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=8, decimal_places=2)
        publish_time = models.DateTimeField(auto_now_add=True)  # 自动添加创建时间
        authors = models.ManyToManyField('Author')
        publish = models.ForeignKey('Publish')  # 一对多
        
        def test(self):
            return self.title+'>>'+str(self.price)
    
    
    class Author(models.Model):
        name = models.CharField(max_length=32)
        age = models.IntegerField()
        authordetail = models.OneToOneField('AuthorDetail')
    
    
    class AuthorDetail(models.Model):
        tel_num = models.BigIntegerField()
        addr = models.CharField(max_length=32)
    
    
    class Publish(models.Model):
        name = models.CharField(max_length=32)
        addr = models.CharField(max_length=32)
        email = models.EmailField()
    
    
    """
    序列化的类
    """
    
    # -*- coding: utf-8 -*-
    
    #  想序列化Book 就要给其写一个序列化的类
    from rest_framework import serializers
    from rest_framework.exceptions import ValidationError
    
    # class BookSerializer(serializers.Serializer):
    #     id = serializers.CharField()
    #     title = serializers.CharField()
    #     price = serializers.CharField()
    #     publish = serializers.CharField()  # 不使用source的时候,可以与表中的字段名相同
    #     publish1 = serializers.CharField(source='publish')  # 字段名不能与前面的序列化的名字一样, 在使用source的时候
    #     publish_name = serializers.CharField(source='publish.name')  # 跨表获取字段属性的值
    #     publish_pk = serializers.CharField(source='publish.pk')  # 跨表
    #     # test1 = serializers.CharField(source='test')  # 方法
    #
    #     # 支持写方法,如下:
    #     # 方法一定要传一个参数,是当前被序列化的book对象
    #     publish_dic = serializers.SerializerMethodField()
    #
    #     def get_publish_dic(self, obj):
    #         # 这里的obj就是当前book对象
    #         return {'id': obj.publish.id, 'name': obj.publish.name}
    
    
    from app01 import models
    
    
    class AuthorSerializer(serializers.Serializer):
        id = serializers.CharField()
        name = serializers.CharField()
        age = serializers.CharField()
    
    
    # ModelSerializer  是与表模型绑定的 Serializer
    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            # 指定表模型
            model = models.Book
            fields = '__all__'  # 表示我要序列化所有字段
            #
            # 只序列化 title 和 id 两个字段
            # fields = ['title','id']
            
            # 其他字段都需要 ,剔除price字段
            # exclude = ['price']  # 该方法和 fields 不能一起用
            
            # 如果想让publish字段显示出版社的名字
            # 跨表深度(连表的深度) 不建议使用,因为下几层的参数无法控制,官方建议不超过十层,实际使用不要超过3
            depth = 1
        
        # publish = serializers.CharField(source='publish.name')
        authors = serializers.SerializerMethodField()
        
        def get_authors(self, obj):
            authors_list = obj.authors.all()
            authors_serializer = AuthorSerializer(authors_list, many=True)
            return authors_serializer.data
        title = serializers.CharField(max_length=6,min_length=3,error_messages={'max_length':'太长了','min_length':'你太短了'})
        # 局部钩子
        # from rest_framework.exceptions import ValidationError --->导入报错信息
        def validate_title(self, value):
            print(value) # 是 title 说对应的值
            if value.startswith('sb'):
                raise ValidationError('不能以sb开头')
            return value
        
        # 全局钩子
        def validate(self, attrs):
            print(attrs)  # 这里的attrs 是一个字典  {'title': 'bbb123', 'price': '999.12', 'authors': 2, 'publish': 2}
            if attrs.get('title').startswith('bbb')and attrs.get('price')>120:
                raise ValidationError('太贵啦,bbb书籍')
            return attrs
    
    """
    views.py
    """
    
    from django.shortcuts import render
    from django.http.response import JsonResponse
    
    # Create your views here.
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from app01 import models
    from app01.myser import BookSerializer
    
    
    class Book(APIView):
        # get 获取所有书籍信息
        def get(self, request, id):
            response = {'status': 100, 'msg': '成功'}
            print(id)
            if not id:
                book_list = models.Book.objects.all()
                # 第一个参数是要序列化的queryset对象,如果要序列化多条,必须制定many=True
                # 当instance形参被传入的实参是单个参数的时候,many=False
                book_serializer = BookSerializer(book_list, many=True)
            else:
                print(id)
                book_obj = models.Book.objects.filter(pk=id).first()
                book_serializer = BookSerializer(book_obj, many=False)
            print(book_serializer.data)
            response['books'] = book_serializer.data
            return Response(response)
        
        def post(self, request, id):
            response = {'status': 100, 'msg': '成功'}
            # 提交的字典
            book = request.data
            # 传统方法,创建对象保存
            print(book)
            
            # 新方法,通过序列化组件保存,必须继承自ModelSerializer
            book_ser = BookSerializer(data=book)
            # is_valid 提交的字段校验通过
            if book_ser.is_valid():
                book_ser.save()
                response['book'] = book_ser.data
            else:
                response['msg'] = book_ser.errors  # errors  是序列化类 中的钩子函数 raise来的报错信息
            return Response(response)
        
        def put(self, request, id):
            response = {'status': 100, 'msg': '修改成功'}
            if id:
                
                # 提交的字典
                book = request.data
                # 传统方法,创建对象保存
                print(book)
                book_obj = models.Book.objects.filter(pk=id).first()
                
                # 新方法,通过序列化组件保存,必须继承自ModelSerializer
                book_ser = BookSerializer(data=book, instance=book_obj)
                # is_valid 提交的字段校验通过
                if book_ser.is_valid():
                    # 这里save()做修改
                    book_ser.save()
                    response['book'] = book_ser.data
                else:
                    response['msg'] = book_ser.errors
            else:
                response['msg'] = '修改对象不存在'
            return Response(response)
        
        def delete(self, request, id):
            models.Book.objects.filter(pk=id).delete()
            response = {'status': 100, 'msg': '删除成功'}
            return Response(response)
    
    

  • 相关阅读:
    bzoj 3732: Network 树上两点边权最值
    思维题题集--------一直都很害怕这些题
    Regionals 2014 >> Asia
    小小粉丝度度熊 二分答案 + two pointer
    I
    Binary Strings Gym
    卸载虚拟机时错误关闭了某个服务,使得电脑除了chrome浏览器都不能联网
    双系统给ubuntu增加分区
    tomcat问题
    eclipse:报错信息The superclass “javax.servlet.http.HttpServlet” was not found on the Java Build Path
  • 原文地址:https://www.cnblogs.com/qianzhengkai/p/11123674.html
Copyright © 2020-2023  润新知