上一节,利用了rest_framework实现了初步的api接口,可以使用get、post、put等类型请求,首先使用serializer.py创建了两个序列化对象,分别是django自带的用户和组对象,然后再编写views函数,最后在urls中使用了router来匹配路由。

序列化实现研究

官方中文文档:https://q1mi.github.io/Django-REST-framework-documentation/tutorial/1-serialization_zh/

  • Serialization类

    • HyperLinkedModelSerializer子类

      • 序列化模型,并添加超级链接(带超级链接的模型序列化工具,常用语ORM开发中)
    • Serializer子类

      • 手动序列化

    使用HyperlinkedModelSerializer序列化

这一篇我们手动在models.py中先创建数据模型models,然后再创建序列化对象。

models

models.py:

from django.db import models

class Book(models.Model):
    b_name=models.CharField(max_length=32)
    b_price = models.FloatField(default=1)

HyperlinkedModelSerializer

接着我们再创建模型的序列化对象HyperlinkedModelSerializer。
serializer.py:

from django.contrib.auth.models import User, Group
from rest_framework import serializers

from REST.models import Book

class BookSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Book
        fields = ('b_name','b_price')

View

views.py

 class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

注册路由

在urls.py注册路由
urls.py:

router.register(r'books', BookViewSet)

迁移数据库

makemigrations
migrate

测试

运行项目

实现了自定义数据模型的序列化,如果还想显示序列化后的url,将serializer.py中添加url参数:

class BookSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Book
        fields = ('url','b_name','b_price')

总结

这样我们就实现了一个模型的快速创建,并且生成了api接口来对数据模型快速进行增删改查的功能。
但是也有缺点

缺点

  • 不知道对模型如何操作
  • 不论用户是谁,都可以对模型进行操作,这里不合理

接下来研究如何如何对数据模型进行操作,并且添加一些限制,限制其只能进行部分操作,并且划分权限,用户智能管理自己的数据,不能对别人的用户数据进行操作。

使用Serializer序列化

创建app

首先先创建一个新的app: python manage.py startapp RESTSerializer

注册到settings中

注册到settings.py的INSTALLED_APPS中.

创建model模型

models.py:

from django.db import models

class Person(models.Model):
    p_name =models.CharField(max_length=32)
    p_age = models.IntegerField(default=1)
    p_sex = models.BooleanField(default=False)

迁移数据库

操作模型

新建urls.py:

from django.urls import path
from RESTSerializer import views

urlpatterns = [
    path(r'persons/', views.PersonView.as_view())
]

注册urls.py: (第5行)

urlpatterns = [
    path(r'admin/', admin.site.urls),
    path(r'cbv/', include(('App.urls', 'cbv'))),
    path(r'rest/', include((router.urls))),
    path(r'ser/', include('RESTSerializer.urls'))
]

views:

from django.shortcuts import render
from django.views import View


class PersonView(View):  # 如果按照传统方式创建get,post请求类,然后来对数据模型操作
    def get(self, request):  # 接收get
        pass
    def post(self, request):  # 接受post
        pass

接下来手动创建序列化器对数据进行操作

新建serializers.py

使用serializers.Serializer序列化工具

serializers设置完模型,还需要我们实现抽象方法:
光标移动到PersonSerializer上使用alt+shift选择lmplement abstract methods


全部选中然后点击ok,就会自动创建方法:

class PersonSerializer(serializers.Serializer):  # 继承原生序列化器
    id = serializers.IntegerField(read_only=True)  # 不可改,所以设置只读
    p_name=serializers.CharField(default=1)
    p_age = serializers.IntegerField(default=1)
    p_sex = serializers.BooleanField(default=False)
    
    def update(self, instance, validated_data):
        pass

    def create(self, validated_data):
        pass

接着我们对update,和create补充功能:

class PersonSerializer(serializers.Serializer):  # 继承原生序列化器
    id = serializers.IntegerField(read_only=True)  # 不可改,所以设置只读
    p_name=serializers.CharField(default=1)
    p_age = serializers.IntegerField(default=1)
    p_sex = serializers.BooleanField(default=False)

    def update(self, instance, validated_data):  # instance是实例
        instance.p_name = validated_data.get('p_name', instance.p_name)  # 从验证通过的数据中拿到p_name然后复制,如果没有获取成功,仍保持原来值
        instance.p_age = validated_data.get('p_age', instance.p_age)  
        instance.p_sex = validated_data.get('p_sex', instance.p_sex)  
        instance.save() # 保存
        
        return instance

    def create(self, validated_data):
        return Person.objects.create(**validated_data)

测试功能

打开shell

(venv) E:\djstudy\day13\RESTApi>python manage.py shell
Python 3.7.5 (tags/v3.7.5:5c02a39a0b, Oct 14 2019, 23:09:19) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from RESTSerializer.models import Person          //导入模块
>>> person = Person()                                 //实例化对象
>>> person.p_name = 'perl'
>>> person.p_age=6
>>> pserson.save()                                    //保存

//需要将数据序列化为json类型
>>> from RESTSerializer.serializers import PersonSerializer   //导入刚刚的序列化器
>>> person_serializer = PersonSerializer(person)  //进行序列化
>>> person_serializer.data  //查看序列化完成之后的对象
{'id': 1, 'p_name': 'perl', 'p_age': 6, 'p_sex': False}

可以看到直接返回字典,接着我们使用json的response等方法就可以直接返回数据。

使用JsonResonse来返回

views.py:

from django.http import JsonResponse
from django.shortcuts import render
from django.views import View

from RESTSerializer.models import Person
from RESTSerializer.serializers import PersonSerializer


class PersonView(View):
    def get(self, request):  # 接收get
        pass
    def post(self, request):  # 接受post
        p_name = request.POST.get('p_name')
        p_age = request.POST.get('p_age')
        
        person = Person()  # 实例化
        person.p_name = p_name
        person.p_age = p_age
        person.save()
        
        person_serializer = PersonSerializer(person)  # 使用序列化器
        return JsonResponse(person_serializer.data)

下面我们测试JsonResponse,运行项目

发现请求403,原因是csrf权限被禁,所以我们先将csrf关闭
再次测试:


成功。

使用ModelSerializers序列化

类似于HyperLinkedModelSerializer,下面实现以下该序列化

创建模型

models.py:

class Student(models.Model):

    s_name = models.CharField(max_length=32)
    s_age = models.IntegerField(default=1)

迁移数据库

使用serializer.ModelSerializer

serializers.py创建学生类:

class StudentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student()
        fields = ('s_name', 's_age')

views

views.py

class StudentView(View):
    def post(self,request):
        s_name = request.POST.get('s_name')
        s_age = request.POST.get('s_age')
        
        student = Student()
        student.s_name = s_name
        student.s_age = s_age
        student.save()
        
        student_serializer = StudentSerializer(student)
        return  JsonResponse(student_serializer.data)

urls注册

urls.py

urlpatterns = [
    path(r'persons/', views.PersonView.as_view()),
    path(r'students/', views.StudentView.as_view()),
]

测试项目


成功。

但是如果某个模型有10个字段,这样还需要我们一个一个手动去写接收代码,很麻烦,有没有什么更好的方法呢?

使用序列化编写常规views

有BUG裂开,有缘再填。

2021/1/19 来填坑,查看    

之前一直序列化的都是单个对象,现在将一个列表或者数组转换成JSON
对Views.py中的PersonView的get进行完善。

class PersonView(View):
    def get(self, request):  # 接收get
        persons = Person.objects.all()  # 先实例化模型
        person_serializer= PersonSerializer(persons, many=True)# 使用many=True参数,直接返回多个数据的json文件格式
        return JsonResponse(person_serializer.data, safe=False)

测试,使用get请求:

以上就是模型序列化的一些知识。

BUG

将Request内容转换成Json格式数据出现BUG

最后修改:2024 年 03 月 13 日
如果觉得我的文章对你有用,请随意赞赏