![](/img/trans.png)
[英]django-rest-framework how to make model serializer fields required
[英]How to extend model on serializer level with 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 MenuItemComponent(models.Model):
menuItem = models.ForeignKey('MenuItem')
component = models.ForeignKey(Component)
isReplaceable = models.BooleanField()
我想要做的是在给定的MenuItem中公开一个包含isReplaceable字段的组件列表(NOT MenuItemComponents)。 到目前为止,我有:
#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列表并强制客户端进行多次调用以检索所有组件。 使用isReplaceable字段中的其他数据公开组件列表可以解决问题。
编辑
最后,我想得到一个列出Component元素的列表,但是这些元素是用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'和'isReplaceable'可以简单地使用默认的只读Field
类。
这里没有完全符合你的'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_object
方法,并使用WritableField
,或者沿着那些行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.