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

后端 未结 1 1747
南方客
南方客 2021-01-01 02:28

My model looks like this:

class MenuItem(models.Model):
    name = models.CharField(max_length=500)
    components = models.ManyToManyField(Component, throug         


        
相关标签:
1条回答
  • 2021-01-01 03:14

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

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

    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.

    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.

    0 讨论(0)
提交回复
热议问题