【问题标题】:AttributeError: 'MovieSerializer' object has no attribute 'id' + SerializationAttributeError:“MovieSerializer”对象没有属性“id”+序列化
【发布时间】:2021-07-03 12:44:39
【问题描述】:

完美的场景是在 MovieSerializer 中使用 RatingSerializer,但由于它低于实际的 mvserializer 代码,我无法使用它。因此,我开始使用 json.dumps() 序列化评分对象,序列化后看起来很丑。

序列化器.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,我已经对其进行了硬编码。

【问题讨论】:

  • 你不能使用底部的RatingSerializer,因为这会导致无限递归:序列化电影会将所有相关的评级与对应的电影序列化,等等。

标签: json django django-models serialization django-rest-framework


【解决方案1】:

您应该过滤obj.id,而不是self,因为self序列化器,而不是序列化器正在处理的对象:

def get_rating(self, obj):
    r = Rating.objects.filter(movie_id=obj.id).values()[0]
    r['rating'] = float(r['rating'])
    return r

不过,使用RatingSerializer 可能会更好。您可以在底部使用RatingSerializer,因为这会导致无限递归:序列化电影会将所有相关评级与对应的电影序列化,等等。 p>

因此,我们可以为Ratings 制作一个简单的(平面)序列化程序,并使用:

class SimpleRatingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Rating
        # no movie
        fields = ['id', 'rating', 'votes']

class MovieSerializer(serializers.ModelSerializer):
    director = PersonSerializer()
    rating = SimpleRatingSerializer(many=True)
    
    class Meta:
        model = Movie
        fields = ['id', 'title', 'director', 'rating']

【讨论】:

  • AttributeError:在序列化程序 MovieSerializer 上尝试获取字段 rating 的值时出现 AttributeError。序列化程序字段可能命名不正确,并且与 Movie 实例上的任何属性或键都不匹配。原始异常文本是:“电影”对象没有“评级”属性。如果尝试您的解决方案,我会收到此错误
  • @Brat: 但是Rating 模型中movieForeignKeyrelated_name 是什么?看起来您在 fields 中的 rating 根本不正确。
【解决方案2】:

最终这工作正常。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-04
    • 2018-06-03
    • 2019-05-23
    • 2015-07-10
    相关资源
    最近更新 更多