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']