我遇到一个问题,即只读属性的行为不符合预期。我看过this question和其他来源试图解决问题,但无济于事。
端点用于保存和列出用户收藏夹。用户可以喜欢多种对象类型,因此我使用内容类型框架。
# serializers.py
class FavouriteSerializer(serializers.ModelSerializer):
user = UserSerializer(read_only=True)
type = serializers.CharField(source='content_type', read_only=True)
object = FavouriteObjectRelatedField(read_only=True)
content_type = serializers.CharField(write_only=True)
object_id = serializers.IntegerField(write_only=True)
def create(self, validated_data, *args, **kwargs):
content_object = Favourites.objects.get_content_object(validated_data.get('object_id'),
validated_data.get('content_type'))
user = kwargs.get('user')
return Favourites.objects.create_favourite(content_object, user)
class Meta:
model = Favourites
fields = ('type', 'object','user','content_type','object_id')
这是根据类型动态序列化对象所需的FavouriteObjectRelatedField
序列化程序。
# serializers.py
class FavouriteObjectRelatedField(serializers.RelatedField):
"""
A custom serializer to use for favourited objects.
"""
def to_representation(self, value):
"""
Serialize favourited objects using their respective serializer
"""
if isinstance(value, Track):
track = TrackBuilder(value).get_info()
serializer = TrackSerializer(track, context=self.context, read_only=True)
elif isinstance(value, News):
serializer = NewsSerializer(value, context=self.context, read_only=True)
else:
raise Exception("Unexpected type of favourited object")
return serializer.data
和观点。我重写perform_create
方法,以便添加从url参数检索的用户实例。
#views.py
class UserFavouritesList(generics.ListCreateAPIView):
permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly)
serializer_class = FavouriteSerializer
def get_user(self):
user_id = self.kwargs.get('user_id')
try:
return get_user_model().objects.get(pk=user_id)
except get_user_model().DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
def perform_create(self, serializer):
serializer.save(user=self.get_user())
def get_queryset(self):
return Favourites.objects.user_favourites(self.get_user())
我总是遇到用户字段错误。但是,如果我删除user
字段,则此错误显然已消失。有趣的是,如果我将user
字段重命名为owner
,我仍会在指定为user
的字段名称中收到相同的错误。错误在这里:
{
"user": [
"This field is required."
]
}
与其中一个答案一样,我已经尝试设置required=True
,但它没有效果。
删除read_only=True
不是一个选项,因为用户实例不应该从此端点进行编辑。
另一个有趣的发展:如果我删除type
字段,它会按预期工作。奇怪但以某种方式访问content_type
字段必须对验证产生影响。
答案 0 :(得分:0)
尝试在那里设置required=False
,而不是read_only=True
。
user = UserSerializer(required=False)