如何使用django-rest-framework在serializer级别上扩展模型 [英] How to extend model on serializer level with django-rest-framework

查看:133
本文介绍了如何使用django-rest-framework在serializer级别上扩展模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的模型看起来像这样:

My model looks like this:

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()

我想做的是公开一个组件列表(NOT MenuItemComponents)在给定的MenuItem中将包含isReplaceable字段。到目前为止,我有:

What I'd like to do is expose a list of Components (NOT MenuItemComponents) in given MenuItem that would include the isReplaceable field. So far I have:

#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字段的附加数据的组件列表将解决问题。

Which exposes a list of MenuItemComponents and forces clients to make multiple calls in order to retrieve all Components. Exposing Components list with additional data from isReplaceable field would solve the problem.

编辑

最后我会喜欢获取列出组件元素的列表,但是使用MenuItemComponent模型中的isReplaceable字段排除元素:

EDIT
In the end I'd like to get a list that lists Component elements but the elements are exteded with isReplaceable field from MenuItemComponent model:

{
    "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实例。

First, create a view that will return the MenuItemComponent instances that you're interested in.

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)

然后,您需要创建一个序列化程序来提供您想要的表示,您的示例比典型的例子有点更有趣/涉及,所以它会看起来像这样...

Then you need to create a serializer to give you the representation you want. Your example is a bit more interesting/involved than the typical case, so it'd look something like this...

class MenuItemComponentSerializer(serializers.Serializer):
    url = ComponentURLField(source='component')
    name = Field(source='component.name')
    isReplaceable = Field()

字段'name'和'isReplaceable'可以简单地使用默认的只读字段类。

The fields 'name' and 'isReplaceable' can simply use the default read-only Field class.

没有任何字段可以满足您的url的情况,因此我们将为此创建一个自定义字段:

There's no field that quite meets your 'url' case here, so we'll create a custom field for that:

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)

我认为这应该是正确的。

I think that should all be about right.

这是一个只读序列化 - 如果你想要一个可写序列化,你需要考虑覆盖 restore_object 方法在序列化器,并使用 WritableField ,或者沿着这些行。

That's for a read-only serialization - if you wanted a writable serialization you'd need to look into overriding the restore_object method on the serializer, and using WritableField, or something along those lines.

这篇关于如何使用django-rest-framework在serializer级别上扩展模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆