|
|
|
from rest_framework import serializers, fields
|
|
|
|
|
|
|
|
from apps.music.models import *
|
|
|
|
|
|
|
|
|
|
|
|
class AlbumSerializer(serializers.Serializer):
|
|
|
|
# 设置外键PrimaryKeyRelatedField
|
|
|
|
artist = serializers.PrimaryKeyRelatedField(label='音乐家', queryset=Musician.objects.all(), many=False,
|
|
|
|
allow_null=False)
|
|
|
|
name = serializers.CharField(label='专辑名', required=True, max_length=10)
|
|
|
|
# 修改字段名称并映射数据模型字段,source为指定模型的字段的字符串形式
|
|
|
|
publish_date = serializers.DateField(label='发行日期', required=False, source='Album.release_date')
|
|
|
|
num_stars = serializers.IntegerField(label='好评度')
|
|
|
|
|
|
|
|
|
|
|
|
class MusicianSerializer(serializers.Serializer):
|
|
|
|
first_name = serializers.CharField(max_length=20, required=True)
|
|
|
|
last_name = serializers.CharField(max_length=20, required=True)
|
|
|
|
instrument = serializers.CharField(max_length=50)
|
|
|
|
# 根据外键的关联关系,将AlbumNameSerializer做为扩展信息
|
|
|
|
album_musician = AlbumSerializer(many=True)
|
|
|
|
|
|
|
|
# 重写create方法
|
|
|
|
def create(self, validated_data):
|
|
|
|
albums_data = validated_data.pop('album_musician')
|
|
|
|
musician = Musician.objects.create(**validated_data)
|
|
|
|
# 插入专辑数据,artist为上一步中插入后返回的对象
|
|
|
|
for album in albums_data:
|
|
|
|
Album.objects.create(artist=musician, **album)
|
|
|
|
return musician
|
|
|
|
|
|
|
|
def update(self, instance, validated_data):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
# class AlbumModelSerializer(serializers.ModelSerializer):
|
|
|
|
# class Meta:
|
|
|
|
# model = Album
|
|
|
|
# fields = ('id', 'artist', 'name', 'release_date', 'num_stars')
|
|
|
|
|
|
|
|
|
|
|
|
class MusicianModelSerializer(serializers.ModelSerializer):
|
|
|
|
# album_musician = AlbumSerializer(read_only=True, many=True) # 定义只读外键字段后在fields中添加此键
|
|
|
|
album_musician = AlbumSerializer(many=True) # 定义只读外键字段后在fields中添加此键,如果需要写入create和update方法,则不应设置readonly
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
model = Musician
|
|
|
|
fields = ('id', 'first_name', 'last_name', 'instrument', 'album_musician')
|
|
|
|
|
|
|
|
# 定义创建数据的方法,用于处理外键的存储
|
|
|
|
def create(self, validated_data):
|
|
|
|
print(validated_data)
|
|
|
|
albums_data = validated_data.pop('album_musician') # 将album_musician对应的数据取出,还原Musician的原始数据格式
|
|
|
|
musician = Musician.objects.create(**validated_data) # 将musician数据入库, 获取返回的musician_id
|
|
|
|
print(musician)
|
|
|
|
for album in albums_data:
|
|
|
|
Album.objects.create(artist=musician, **album) # 遍历albums数据将数据入库
|
|
|
|
return musician
|
|
|
|
|
|
|
|
# 定义创修改的方法,用于处理外键存储
|
|
|
|
def update(self, instance, validated_data): # instance为pk指定的数据库对象实例
|
|
|
|
print(instance)
|
|
|
|
print(validated_data)
|
|
|
|
albums_data_req = validated_data.pop('album_musician') # 将album_musician对应的数据取出,还原Musician的原始数据格式
|
|
|
|
albums_db = instance.album_musician.all() # 获取原始的album外键数据
|
|
|
|
albums_db = list(albums_db)
|
|
|
|
print(albums_db)
|
|
|
|
# 从validated_data中获取字段的值,如果没有获取到就取数据库实例的对应值,并且更新数据
|
|
|
|
instance.first_name = validated_data.get('first_name', instance.first_name)
|
|
|
|
instance.last_name = validated_data.get('last_name', instance.last_name)
|
|
|
|
instance.instrument = validated_data.get('instrument', instance.instrument)
|
|
|
|
instance.save()
|
|
|
|
|
|
|
|
# 更新album数据
|
|
|
|
for album_data_req in albums_data_req:
|
|
|
|
album_db = albums_db.pop(0)
|
|
|
|
album_db.name = album_data_req.get('name', album_db.name)
|
|
|
|
album_db.release_date = album_data_req.get('release_date', album_db.release_date)
|
|
|
|
album_db.num_stars = album_data_req.get('num_stars', album_db.num_stars)
|
|
|
|
album_db.save()
|
|
|
|
return instance
|