Python 如何使用django rest框架在序列化程序级别扩展模型
我的模型如下所示:Python 如何使用django rest框架在序列化程序级别扩展模型,python,django-rest-framework,Python,Django Rest Framework,我的模型如下所示: class MenuItem(models.Model): name = models.CharField(max_length=500) components = models.ManyToManyField(Component, through=MenuItemComponent) class Component(models.Model): name = models.CharField(max_length=500) class MenuI
class MenuItem(models.Model):
name = models.CharField(max_length=500)
components = models.ManyToManyField(Component, through=MenuItemComponent)
class Component(models.Model):
name = models.CharField(max_length=500)
class MenuItemComponent(models.Model):
menuItem = models.ForeignKey('MenuItem')
component = models.ForeignKey(Component)
isReplaceable = models.BooleanField()
我想做的是在给定的MenuItem中公开一个组件列表(而不是MenuItemComponents),其中包括isreplacable字段。到目前为止,我已经:
#views.py
class MenuItemComponentList(generics.ListAPIView):
"""
Displays components for given MenuItem
"""
model = MenuItemComponent
serializer_class = MenuItemComponentSerializer
def get_queryset(self):
itemId = self.kwargs['itemId']
return MenuItemComponent.objects.filter(menuItem__pk=itemId)
#serializers.py
class MenuItemComponentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = MenuItemComponent
它公开了MenuItemComponents的列表,并强制客户端进行多次调用以检索所有组件。使用isreplacable字段中的附加数据公开组件列表可以解决此问题
编辑最后,我想得到一个列出组件元素的列表,但这些元素是通过MenuItemComponent模型中的isReplaceable字段扩展的:
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"url": "http://localhost:8000/api/component/1/",
"name": "component 1",
"isReplaceable": true
},
{
"url": "http://localhost:8000/api/component/2/",
"name": "component 2",
"isReplaceable": false
}
]
}
首先,创建一个视图,该视图将返回您感兴趣的MenuItemComponent实例
class ListComponents(generics.ListAPIView):
serializer_class = MenuItemComponentSerializer
def get_queryset(self):
"""
Override .get_queryset() to filter the items returned by the list.
"""
menuitem = self.kwargs['menuitem']
return MenuItemComponent.objects.filter(menuItem=menuitem)
然后,您需要创建一个序列化程序来提供所需的表示。您的示例比典型案例更有趣/更复杂,所以看起来像这样
class MenuItemComponentSerializer(serializers.Serializer):
url = ComponentURLField(source='component')
name = Field(source='component.name')
isReplaceable = Field()
字段“name”和“isreplacable”可以简单地使用默认的只读字段
类
这里没有完全符合“url”情况的字段,因此我们将为此创建一个自定义字段:
class ComponentURLField(serializers.Field):
def to_native(self, obj):
"""
Return a URL, given a component instance, 'obj'.
"""
# Something like this...
request = self.context['request']
return reverse('component-detail', kwargs=kwargs, request=request)
我认为这应该是正确的
这是针对只读序列化的—如果您想要一个可写的序列化,您需要研究重写序列化程序上的
restore\u object
方法,并使用WritableField
,或者类似的方法。您可以举一个示例,说明您希望最终表示形式是什么样的吗?