AttributeError: 'MovieSerializer' object has no attribute 'id' + Serialization
AttributeError: 'MovieSerializer' object has no attribute 'id' + Serialization
完美的方案是在 MovieSerializer 中使用 RatingSerializer,但由于它低于实际的 mvserializer 代码,我无法使用它。因此,我开始使用 json.dumps() 序列化评级对象,序列化后看起来非常丑陋。
serializers.py
class MovieSerializer(serializers.ModelSerializer):
id = 15414
director = PersonSerializer()
rating = serializers.SerializerMethodField() # I want to use here RatingSerializer()
def get_rating(self, obj):
r = list(Rating.objects.filter(movie_id=self.id).values())[0]
r['rating'] = float(r['rating'])
return json.dumps(r)
class Meta:
model = Movie
fields = ['id', 'title', 'director', 'rating']
class RatingSerializer(serializers.ModelSerializer):
movie = MovieSerializer()
class Meta:
model = Rating
fields = ['id', 'movie', 'rating', 'votes']
结果,评分字段序列化的很糟糕
{
"id": 16906,
"title": "Frivolinas",
"director": {
"id": 2014,
"name": "Iron Eyes Cody",
"birth": 1907
},
"rating": "{\"id\": 1, \"movie_id\": 15414, \"rating\": 5.4, \"votes\": 12}"
},
有没有办法在 MovieSerializer 中使用 RatingSerializer?
这样做(我的方式),我也找不到 get_rating 方法中的实际 ID,我已经对其进行了硬编码。
您应该过滤 obj
的 .id
,而不是 self
,因为 self
是 序列化程序 ,而不是序列化程序正在处理的对象:
def get_rating(self, obj):
r = Rating.objects.filter(movie_id=<b>obj.id</b>).values()[0]
r['rating'] = float(r['rating'])
return r
然而,使用 RatingSerializer
可能会更好。您可以不使用底部的RatingSerializer
,因为这会导致无限递归:序列化电影会将所有相关评级与具有相应评级的相应电影序列化等
因此,我们可以为 Rating
制作一个简单的(平面)序列化程序,并使用:
class SimpleRatingSerializer(serializers.ModelSerializer):
class Meta:
model = Rating
# <i>no</i> movie
fields = ['id', 'rating', 'votes']
class MovieSerializer(serializers.ModelSerializer):
director = PersonSerializer()
rating = <b>SimpleRatingSerializer(many=True)</b>
class Meta:
model = Movie
fields = ['id', 'title', 'director', 'rating']
最终这很好用。
class MovieSerializer(serializers.ModelSerializer):
director = PersonSerializer()
rating = serializers.SerializerMethodField()
votes = serializers.SerializerMethodField()
def get_rating(self, obj):
r = list(Rating.objects.filter(movie_id=obj.id).values())[0]
return json.dumps(float(r['rating']))
def get_votes(self, obj):
r = list(Rating.objects.filter(movie_id=obj.id).values())[0]
return json.dumps(r['votes'])
class Meta:
model = Movie
fields = ['id', 'title', 'director', 'rating', 'votes']
完美的方案是在 MovieSerializer 中使用 RatingSerializer,但由于它低于实际的 mvserializer 代码,我无法使用它。因此,我开始使用 json.dumps() 序列化评级对象,序列化后看起来非常丑陋。
serializers.py
class MovieSerializer(serializers.ModelSerializer):
id = 15414
director = PersonSerializer()
rating = serializers.SerializerMethodField() # I want to use here RatingSerializer()
def get_rating(self, obj):
r = list(Rating.objects.filter(movie_id=self.id).values())[0]
r['rating'] = float(r['rating'])
return json.dumps(r)
class Meta:
model = Movie
fields = ['id', 'title', 'director', 'rating']
class RatingSerializer(serializers.ModelSerializer):
movie = MovieSerializer()
class Meta:
model = Rating
fields = ['id', 'movie', 'rating', 'votes']
结果,评分字段序列化的很糟糕
{
"id": 16906,
"title": "Frivolinas",
"director": {
"id": 2014,
"name": "Iron Eyes Cody",
"birth": 1907
},
"rating": "{\"id\": 1, \"movie_id\": 15414, \"rating\": 5.4, \"votes\": 12}"
},
有没有办法在 MovieSerializer 中使用 RatingSerializer? 这样做(我的方式),我也找不到 get_rating 方法中的实际 ID,我已经对其进行了硬编码。
您应该过滤 obj
的 .id
,而不是 self
,因为 self
是 序列化程序 ,而不是序列化程序正在处理的对象:
def get_rating(self, obj):
r = Rating.objects.filter(movie_id=<b>obj.id</b>).values()[0]
r['rating'] = float(r['rating'])
return r
然而,使用 RatingSerializer
可能会更好。您可以不使用底部的RatingSerializer
,因为这会导致无限递归:序列化电影会将所有相关评级与具有相应评级的相应电影序列化等
因此,我们可以为 Rating
制作一个简单的(平面)序列化程序,并使用:
class SimpleRatingSerializer(serializers.ModelSerializer):
class Meta:
model = Rating
# <i>no</i> movie
fields = ['id', 'rating', 'votes']
class MovieSerializer(serializers.ModelSerializer):
director = PersonSerializer()
rating = <b>SimpleRatingSerializer(many=True)</b>
class Meta:
model = Movie
fields = ['id', 'title', 'director', 'rating']
最终这很好用。
class MovieSerializer(serializers.ModelSerializer):
director = PersonSerializer()
rating = serializers.SerializerMethodField()
votes = serializers.SerializerMethodField()
def get_rating(self, obj):
r = list(Rating.objects.filter(movie_id=obj.id).values())[0]
return json.dumps(float(r['rating']))
def get_votes(self, obj):
r = list(Rating.objects.filter(movie_id=obj.id).values())[0]
return json.dumps(r['votes'])
class Meta:
model = Movie
fields = ['id', 'title', 'director', 'rating', 'votes']