使用Django2.0构建Python Restful Web服务:十)创建模型序列化器

在上一小篇文章中,我们设计并创建和新的Django项目的模型,本篇我们继续《使用Django 2.0构建Python Restful Web服务》。今天我们来为模型创建序列化和反序列化器,对电影分类模型、电影模型、观众模型、和电影评分模型分别创建模型的序列化器。

在这里,我们的模型之间都是有相互的关联关系的,为了体现模型之间的关联性,我们在创建序列化器的时候也需要考虑到。

一、使用超链接序列化器

在本系列教程的第五篇,我们曾经使用rest_framework的序列化类创建过一个简单的模型序列化器,而在本篇文章中,我们则使用更加高级的超链接模型序列化器——HyperlinkedModelSerializer()。超链接模型序列化器有什么特别之处呢,我们来看看rest_framwork源码中的介绍:

    """     A type of `ModelSerializer` that uses hyperlinked relationships instead     of primary key relationships. Specifically:      * A 'url' field is included instead of the 'id' field.     * Relationships to other instances are hyperlinks, instead of primary keys.     """ 

简而言之就是通过超链接的形式来表示模型之间的关系,并通过url字段与其他模型进行连接。这样的概念似乎不是很清晰,下面我们通过实际的代码来演示一下。

在userscore目录下创建一个名为serializers.py的文件,我们的模型序列化器就在这里面进行定义

二、电影分类模型序列化器

电影分类模型的序列化器是我们定义的第一个序列化器,我们在serializers.py文件中写入以下代码:

# 电影分类序列化器 class MovieCategorySerializer(serializers.HyperlinkedModelSerializer):     # 使用超链接关系字段     movies = serializers.HyperlinkedRelatedField(         many=True, # 表示序列化多个对象         read_only=True,# 表示在序列化时使用,反序列化时不使用         view_name = 'movie-detail' # 绑定对应的超链接视图函数名,默认情况下为:模型名称-detail     )      class Meta:         model = MovieCategory # 序列化器对应的模型         # 序列化器返回的字段         fields = (             'url',             'pk',             'name',             'movies'         ) 

在MovieCategorySerializer序列化器中,我们继承了超链接模型序列化器HyperlinkedModelSerializer,然后使用超链接关系字段HyperlinkedRelatedField来声明movies字段,同时使用many属性设置该序列化器序列化多个对象,使用read_only属性设置其用于只读状态,使用view_name属性确定超链接的视图函数。

三、电影序列化器

对于电影序列化器,我们依然继承自HyperlinkedModelSerializer(),同时在电影序列化器中使用序列化器的标签关系字段SlugRelatedField()来描述电影分类字段,最后,在Meta()中声明电影序列化器使用到的模型Movie和各个字段。电影序列化器MovieSerializer()的代码如下所示:

# 电影序列化器 class MovieSerializer(serializers.HyperlinkedModelSerializer):     # 使用标签关系字段定义分类     movie_category = serializers.SlugRelatedField(queryset=MovieCategory.objects.all(),slug_field='name')      class Meta:         model = Movie         fields = (             'url',             'movie_category',             'name',             'release_date',             'viewed',         ) 

四、电影评分序列化器

在模型model中,我们的电影评分模型中有两个外键字段——观众字段和电影字段,这些外键字段需要我们在创建序列化器的时候进行另外的处理。在电影评分序列化器中,外键字段我们只设置电影的字段,观众字段我们将在观众序列化器中将电影评分序列化器包含进去。所以,电影评分序列化器的代码如下:

# 电影评分序列化器 class ScoreSerializer(serializers.ModelSerializer):     movie = MovieSerializer()      class Meta:         model = MovieScore         fields = (             'url',             'pk',             'score',             'score_date',             'movie'         ) 

五、观众序列化器

现在轮到了观众序列化器。在电影评分序列化器中,我们没有将观众字段添加进行,因为我们将在观众序列化器添加评分字段,而这在观众模型中是不存在的。所以观众序列化器的代码如下所示:

# 观众序列化器 class ViewerSerializer(serializers.HyperlinkedModelSerializer):     scores = ScoreSerializer(many=True,read_only=True)     gender = serializers.ChoiceField(choices=Viewer.GENDER_CHOICES)     gender_description = serializers.CharField(source='get_gender_display',read_only=True)      class Meta:         model = Viewer         fields = (             'url',             'name',             'gender',             'gender_description',             'scores'         ) 

六、观众评分序列化器

除了模型中对应的各个模型的序列化器,我们再创建一个综合的序列化器——观众评分序列化器,用于获得观众的电影评分。其代码如下所示:

# 观众评分序列化器 class ViewerScoreSerializer(serializers.ModelSerializer):     Viewer = serializers.SlugRelatedField(queryset=Viewer.objects.all(), slug_field='name')     movie = serializers.SlugRelatedField(queryset=Movie.objects.all(), slug_field='name')      class Meta:         model = MovieScore         fields = (             'url',             'pk',             'score',             'score_date',             'viewer',             'movie'         ) 

最后

这样,我们就创建完了Django项目所需的所有模型序列化器,下一步,我们将创建在视图函数中对数据进行反序列化。有疑问欢迎留言讨论。