Reputation: 1572
I want to have an endpoint for every image I want to add tags in.
Suppose I have:
#models.py
class ImageTag(models.Model):
name = models.CharField()
description = models.CharField()
class Image(models.Model):
image_id = models.CharField(unique=True)
image_tags = models.ManyToManyField(ImageTag, blank=True)
...
#serializers.py
class ImageSerializer(serializers.ModelSerializer):
class Meta:
model = Image
fields = '__all__'
#views.py
class ImageViewSet(viewsets.ModelViewSet):
queryset = Image.objects.all()
serializer_class = ImageSerializer
lookup_field = 'image_id'
...
#urls.py
router.register(r'images', ImageViewSet, basename='image')
I want to POST and DELETE image_tags in an endpoint such as:
localhost:8000/my_app/images/IMG_123/image_tags
where: IMG_123 is an Image
I think I will need a separate serializer and viewset for that. But more importantly I want to know how will I add such endpoint in the router
in urls.py
I am looking for something like this:
router.register(r'<image>/image_tags', ImageTagViewSet, basename='image_tag')
NOTE: I was able to change Image endpoint using its image_id
(instead of ID) because of lookup_field
in ImageViewSet
, thus can be:
localhost:8000/my_app/images/IMG_123/
Upvotes: 0
Views: 1384
Reputation: 571
you can create custom endpoint for a viewset whit defining extra actions
you will create a method with action
decorator and the router of this viewset will create url from that method name for you for example:
from rest_framework.decorators import action
class ImageViewSet(viewsets.ModelViewSet):
queryset = Image.objects.all()
serializer_class = ImageSerializer
lookup_field = 'image_id'
@action(detail=True, methods=['post'])
def image_tags(self, request, *args, **kwargs):
image_instance = self.get_object() # image that it's id has been passed by url
# you can now filter and get your ImageTags and serialize it with a serializer
this will create an endpoint like you want it
localhost:8000/my_app/images/IMG_123/image_tags/
Upvotes: 2
Reputation: 194
class ImageViewSet(viewsets.ModelViewSet):
image_id = self.kwargs['id']
queryset = Image.objects.get(image_id=image_id)
serializer_class = ImageSerializer
lookup_field = 'image_id'
...
router.register(r'(?P<id>[a-zA-Z0-9_]+)/image_tags$', ImageTagViewSet, basename='image_tag')
Upvotes: 1