简体   繁体   English

如何使用django-rest-framework在序列化程序级别上扩展模型

[英]How to extend model on serializer level with django-rest-framework

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

What I'd like to do is expose a list of Components (NOT MenuItemComponents) in given MenuItem that would include the isReplaceable field. 我想要做的是在给定的MenuItem中公开一个包含isReplaceable字段的组件列表(NOT MenuItemComponents)。 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

Which exposes a list of MenuItemComponents and forces clients to make multiple calls in order to retrieve all Components. 其中公开了MenuItemComponents列表并强制客户端进行多次调用以检索所有组件。 Exposing Components list with additional data from isReplaceable field would solve the problem. 使用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: 最后,我想得到一个列出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
        }
    ]
}

First, create a view that will return the MenuItemComponent instances that you're interested in. 首先,创建一个视图,返回您感兴趣的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)

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

The fields 'name' and 'isReplaceable' can simply use the default read-only Field class. 字段'name'和'isReplaceable'可以简单地使用默认的只读Field类。

There's no field that quite meets your 'url' case here, so we'll create a custom field for that: 这里没有完全符合你的'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)

I think that should all be about right. 我认为这一切都应该是正确的。

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. 这是一个只读序列化 - 如果你想要一个可写序列化,你需要考虑覆盖序列化器上的restore_object方法,并使用WritableField ,或者沿着那些行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 django-rest-framework 如何使模型序列化器字段成为必需 - django-rest-framework how to make model serializer fields required 如何在Django-rest-framework序列化器中的关系模型中获得额外的列? - How to get an extra column in relational model in Django-rest-framework serializer? 如何编写django-rest-framework序列化程序以保存包含通用模型的嵌套层次结构? - How do I write a django-rest-framework serializer to save a nested hierarchy containing a generic model? 如何在 django-rest-framework 的序列化器中使用时区序列化时间? - how to serialize time with timezone in django-rest-framework's serializer? 如何在django-rest-framework中将参数传递给序列化器? - How to pass arguments to a Serializer in django-rest-framework? 如何在Django-rest-framework中序列化列表? - how can I serializer a list in django-rest-framework? django-rest-framework 中的可写嵌套序列化程序? - Writable nested serializer in django-rest-framework? Django-Rest-Framework中序列化器的问题 - Issues with Serializer in Django-Rest-Framework django-rest-framework:使用 ENUMS 和 source='get_label_display' 时的 model 序列化程序 - django-rest-framework: model serializer when using ENUMS and source='get_label_display' 如何将模型方法公开给django-rest-framework - How to expose model methods to django-rest-framework
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM