django---rest-framework序列化

本文介绍如何在 Django REST Framework 中使用 ModelSerializer 和 APIView 构建 RESTful API,包括序列化模型数据、实现自定义序列化字段以及使用分页等关键实践。

APIView Serializer

models

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

url

url(r"books/$",views.BookView.as_view())

views

from django.shortcuts import render,HttpResponse


from rest_framework import viewsets
from rest_framework import serializers
from .models import *
from rest_framework.views import APIView
from rest_framework.response import Response



class BookSerializers(serializers.Serializer):
    title=serializers.CharField(max_length=32)
    price=serializers.IntegerField()
    pub_date=serializers.DateField()
    publish=serializers.CharField(source="publish.pk")
    #authors=serializers.CharField(source="authors.all")
    # 针对多对多
    authors = serializers.SerializerMethodField()
    def get_authors(self,obj):
        temp=[]
        for author in obj.authors.all():
            temp.append({"pk":author.pk,"name":author.name})
        return temp


class BookView(APIView):

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

        book_list = Book.objects.all()
        # 方式1:
        # book_list=list(Book.objects.all().values("title","price"))
        # print(book_list)
        # 方式2
        # temp=[]
        # for book in book_list:
        #     temp.append({
        #         "title":book.title,
        #         "price":book.price,
        #         "pub_date":book.pub_date,
        #     })
        #
        # 方式3:
        # from django.core import serializers
        # temp=serializers.serialize("json",book_list)
        # return HttpResponse(temp)

        # 方式4:
        # 将book_list转换为json数据[{},{},{}]
        # 当我们输入参数many = True时, serializer还能序列化queryset
        bs = BookSerializers(book_list, many=True)
        print(bs.data)  # 序列化的结果
        return Response(bs.data)

测试如下:
http://127.0.0.1:8000/books/

[
  {
    "title": "java",
    "price": 2,
    "pub_date": null,
    "publish": "1",
    "authors": [
      {
        "pk": 1,
        "name": "safly"
      },
      {
        "pk": 2,
        "name": "xiaowang"
      }
    ]
  },
  {
    "title": "go",
    "price": 44,
    "pub_date": null,
    "publish": "1",
    "authors": [
      {
        "pk": 1,
        "name": "safly"
      }
    ]
  },
  {
    "title": "php",
    "price": 22,
    "pub_date": null,
    "publish": "2",
    "authors": [
      {
        "pk": 1,
        "name": "safly"
      }
    ]
  }
]

ModelSerializer

class BookSerializers(serializers.ModelSerializer):
    class Meta:
        model=Book
        fields="__all__"

    authors = serializers.SerializerMethodField()
    def get_authors(self,obj):
        temp=[]
        for author in obj.authors.all():
            temp.append({"pk":author.pk,"name":author.name})
        return temp

经过测试效果一样

APIView中使用dispatch


class BookView(APIView):

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


        book_list = Book.objects.all()

        bs = BookSerializers(book_list, many=True)

        return HttpResponse(bs.data)

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

        ret = super(BookView, self).dispatch(request, *args, **kwargs)

        return HttpResponse(ret)

需要使用原生的HttpResponse,如果使用Response(bs.data)会报错,这个我后续在源码中在进行分析

代码示例

from rest_framework.views import APIView
from rest_framework.viewsets import GenericViewSet
from rest_framework.response import Response
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
from django.core.exceptions import ObjectDoesNotExist
from api import models
from api.response.base import BaseResponse
from api.serializers.course import CourseSerializer,CourseDetailSerializer
from api.pagination.page import LuffyPageNumberPagination

class MyException(Exception):
    def __init__(self,msg):
        self.msg = msg



class CourseView(GenericViewSet):
    renderer_classes = [JSONRenderer,BrowsableAPIRenderer]
    def list(self,request,*args,**kwargs):
        """
        获取课程列表
        :return:
        """
        # queryset = [{id:,,name:...},{id:,,name:...},]
        # 方式一:
        # select id,name from course
        # course_list = queryset类型[{id:,,name:...},{id:,,name:...},]
        # course_list = models.DegreeCourse.objects.all().values('id','name')
        # course_list = list(course_list)
        # val = json.dumps(course_list,ensure_ascii=False)
        # return  HttpResponse(val)
        # 方式二:
        # course_list = models.DegreeCourse.objects.all().values('id','name')
        # course_list = list(course_list)
        # return JsonResponse(course_list,safe=False,json_dumps_params={'ensure_ascii':False})

        # 方法三:
        # select id,name from course
        # course_list=Queryset=[obj,obj,obj,obj, obj,obj,obj,obj,obj,obj, ]
        # course_list = models.DegreeCourse.objects.all().defer('name')

        """
        ret = {'code':1000,'data':None,'error':None}
        try:
            # QuerySet,是django的类型
            # 1. 获取数据
            course_list = models.DegreeCourse.objects.all().only('id','name').order_by('-id')
            # 2. 对数据进行分页
            page = LuffyPageNumberPagination()
            page_course_list = page.paginate_queryset(course_list,request,self)
            # 3. 对数据序列化
            ser = CourseSerializer(instance=page_course_list,many=True)
            ret['data'] = ser.data
        except Exception as e:
            ret['code'] = 1001
            ret['error'] = '获取数据失败'
        return Response(ret)
        """
        ret = BaseResponse()
        try:
            # QuerySet,是django的类型
            # 1. 获取数据
            course_list = models.DegreeCourse.objects.all().only('id', 'name').order_by('-id')
            # 2. 对数据进行分页
            page = LuffyPageNumberPagination()
            page_course_list = page.paginate_queryset(course_list, request, self)

            # 3. 对数据序列化
            ser = CourseSerializer(instance=page_course_list, many=True)
            ret.data = ser.data
        except Exception as e:
            ret.code = 1001
            ret.error = '获取数据失败'
        return Response(ret.dict)

    def retrieve(self,request,pk,*args,**kwargs):

        """
            示例1:
                ret = BaseResponse()
                try:
                    obj = models.DegreeCourse.objects.filter(id=pk).first()
                    if not obj:
                        raise MyException('数据不存在')
                except MyException as e:
                    ret.code = 1001
                    ret.error = e.msg
                except Exception as e:
                    ret.code = 1002
                    ret.error = str(e)
                return Response(ret.dict)
        """

        # 示例2:
        ret = BaseResponse()
        try:
            obj = models.DegreeCourse.objects.get(id=pk)
            # obj = CourseDetailSerializer.__new__
            # obj.__init__
            # many=False,
            #       obj= CourseDetailSerializer的对象来进行序列化数据。
            #       obj.__init__
            # many=True
            #       obj = ListSerializer() 的对象来进行序列化数据。
            #       obj.__init__
            ser = CourseDetailSerializer(instance=obj, many=False)
            ret.data = ser.data
        except ObjectDoesNotExist as e:
            ret.code = 1001
            ret.error = '查询数据不存在'
        except Exception as e:
            ret.code = 1002
            ret.error = "查询失败"
        return Response(ret.dict)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值