上一节,利用了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)
迁移数据库
测试
运行项目
实现了自定义数据模型的序列化,如果还想显示序列化后的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
此处评论已关闭