Django REST framework序列化器是什么
在Django中,序列化器是将模型类转换成Json或者Xml格式数据并对数据进行验证,具体表现在:
1,Django从后台向前台传递数据时将会将模型类转换成Json格式数据返回给前端,
2,前端向后台请求数据时对数据进行验证并处理数据(验证数据不一定处理,但是处理数据时必须先验证数据),
为什么要返回Json数据
Json是一种简单的数据交换格式,因为格式简洁,易于读取,这样前台就可以一眼就看出数据中的内容,方便检查排错同时可通过JavaScript进行解析,不管传输还是解析效率都很高,所以一般前台都会要求后台返回json格式的数据。
Django怎么返回Json数据
现在我们在models.py中新建一个模型类,这里我定义一个电影类,这里我定义了3个简单的类,在film中关联了其他2个类。
from django.db import models
from rest_framework.permissions import IsAuthenticated
# Create your models here.
class Performer(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
class Meta:
db_table = 'performer'
class Type(models.Model):
type = models.CharField(max_length=20)
def __str__(self):
return self.type
class Meta:
db_table='type'
class Film(models.Model):
film_name = models.CharField(max_length=50,null=False)
performer = models.ForeignKey(Performer,on_delete=models.CASCADE)
film_type = models.ForeignKey(Type,on_delete=models.CASCADE)
time = models.DateField()
film_url = models.URLField()
desc = models.TextField()
def __str__(self):
return self.film_name
class Meta:
db_table = 'Film'
为了更加方便快捷的操作,这里我创建了一个Django超级管理员,在admin后台添加了些简单的数据进去,在admin.py文件中注册下我们的模型类,如下图所示。
from django.contrib import admin
from user.models import Performer,Type,Film
# Register your models here.
class FilmAdmin(admin.ModelAdmin):
# 指定要显示的属性
list_display = ["id", "film_name", "performer", "film_type", "time", "film_url", "desc"]
admin.site.register(Performer)
admin.site.register(Type)
admin.site.register(Film,FilmAdmin)
下来我们就来通过视图获取电影的全部数据,现在我们新建一个测试文件dome.py,我们来测试下我们获取到的数据格式,首先我先设置文件然后导入这几张表和models,没有前面这三行程序会报错:django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings。
import os,django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "untitled.settings")# untitled 项目名称
django.setup()
from user.models import Film,Type,Performer
movies=Film.objects.all()
print(movies,type)
这里我们可以看到,获取到的是个 QuerySet对象
接着我们继续获取,使用Django为我们提供的values方法来获取对象中的值,这里我们可以看到我们已经可以读取到对应的数据和关联键了,但这里我们获取到的数据类型还是QuerySet对象。
现在用list()方法转换下数据类型,将QuerySet对象强制转换成数组,这里我们可以看到前面已经没有显示QuerySet,而是[{...},{...}]数组格式。
但这里我们还发现个问题,在这些数据中还有两个外键关联的数据并没有显示值,而是对应的id,要获取这两个外键的值我们还需要获取Type和Performer的列表信息,通过指定的id来获取对应的值,这里我们可以直接用filter方法来获取,这样我们才算真正获取到了我们需要的所有参数值了。
总结:通过Django我们需要将数据进行几次转换才能提取到我们所需的数据信息,出现关联时我们还需要进一步的对数据进行查询获取,操作还是挺麻烦的。
接下来我们用REST framework序列化器来试试同样获取当前的数据,看看是如何操作的。首先我们目前已经建立了数据模型类,所以这里我们直接在当前文件下创建一个序列化器,新建一个serializers.py文件,引入serializers:from rest_framework import serializers,接着导入我们的模型类。
from rest_framework import serializers
# 在序列化器中导入用户的ORM模型
from user.models import Film
from user.models import Performer
from user.models import Type
class Performerserializer(serializers.ModelSerializer):
class Meta:
model = Performer
fields = '__all__'
class TypeSerializer(serializers.ModelSerializer):
class Meta:
model=Type
fields = '__all__'
class FilmSerializer(serializers.ModelSerializer):
per = Performerserializer()
type = TypeSerializer()
class Meta:
model = Film
fields = ('id', 'film_name', 'time', 'film_url', 'desc', 'performer', 'film_type')
同样我们用dome.py来测试下获取的数据时什么样的,我们可以从下图中看出,通过使用REST framework序列化器,我们可以很简单的获取到我们想要的数据,而不用进行多次的转换。
这里我们看到后台获取到的是OrderedDict数据,这是一种有序的字典数据结构。那么前台拿到的是什么类型的呢,这里我们写个视图函数输出一下,在views.py中我们写个简单的视图,然后配上路由。
#url.py
from django.contrib import admin
from django.urls import path
from user import views
from rest_framework.routers import DefaultRouter
urlpatterns = [
path('admin/', admin.site.urls),
path('movies/',views.movieViews.as_view()),
]
#views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from user.serializers import *
from user.models import *
# Create your views here.
class movieViews(APIView):
def get(self, request):
movies = Film.objects.all()
serializer = FilmSerializer(movies, many=True)
return Response(serializer.data)
现在我们启动下服务,看下该路由下获取到的数据到底是什么形式的,这里我们可以看到给前台返回的数据是个列表元素,每部电影的数据意字典的形式嵌套在里面,而外键中的数据同样以字典的形式内嵌在电影中,前台只要依次遍历就可以获取到对应的数据了。
通过上述的实战演示我们可以看到出来使用Serializer给我们带来很多的便利。