我正在尝试使用Django Rest Framework实现某些功能。 这个想法是让一个模型在只读中有几个类型的几个字段,并且具有可供用户写入的相同字段,这些字段在提供数据时优先。 由于这不应该非常清楚,例如:
该模型将是:
class Site(models.Model):
title = models.CharField(_('Title'),max_length=300)
title_modified = models.CharField(_('Title'),max_length=300)
要定义的视图集:
class SiteViewSet(viewsets.ModelViewSet):
serializer_class = SiteSerializer
queryset = Site.objects.all()
序列化器:
class SiteSerializer(serializers.ModelSerializer):
class Meta:
model = Site
depth = 1
我想要做的是只能向客户端提供“标题”数据,但如果title_modified为空,则标题将具有title字段,如果title_modified字段不为空,则标题将具有title_modified字段。 同样的想法,当客户端写入标题时,我希望我的服务器将数据写入title_modified,并始终保持标题信息不变。
我不知道如何以足够通用的方式实现这一点,以适用于所有类型的领域。 我认为在序列化/反序列化上只需要一些魔法,但我似乎无法找到它。
任何想法都会受到赞赏。 感谢。
答案 0 :(得分:2)
由于您使用的是ModelViewSets,因此您可以覆盖默认操作,如.list(),. retrieve(),. create()等,以执行您想要的操作或创建自定义操作。可以找到ModelViewSets的相关信息here和here。
实际上,有很多方法可以解决这个问题,甚至不需要使用ModelViewSet。您实际上可以使用此通用视图。真正的诀窍是通常利用CBV和OOP的力量。下面是一个示例代码,其中提供了单个实例的自定义检索过程,同时保留了ModelViewSet提供的所有其他开箱即用的行为。
class SiteViewSet(viewsets.ModelViewSet):
serializer_class = SiteSerializer
queryset = Site.objects.all()
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
# You can use the serializer_class specified above (SiteSerializer)
serializer = self.get_serializer(instance)
# Or perform some other manipulation on your instance first,
# then use a totally different serializer for your needs
instance = data_manipulation(instance)
serializer = AnotherSiteSerializer(instance)
# Finally return serialized data
return Response(serializer.data)
# Or if you want, return random gibberish.
return Response({'hello': 'world'})
答案 1 :(得分:1)
我认为您可以覆盖序列化程序的to_representation()方法来解决您的问题:
class SiteSerializer(serializers.ModelSerializer):
class Meta:
model = Site
depth = 1
exclude = ('title')
def to_representation(self, instance):
rep = super(SiteSerializer, self).to_representation(instance)
if not rep.get('title_modified', ''):
rep['title_modified'] = instance.title
return rep
如果title_modified为空,这将返回title_modified标题。用户将始终根据需要处理title_modified。 有关详细信息,请参阅modelserializer和Advanced serializer usage。