4

I have two models say A and B.

models look like

class A(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=1000)
    slug = models.CharField(max_length=100)

class B(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=1000)
    slug = models.CharField(max_length=100)
    A = models.foreignkey(A, models.SET_NULL, blank=true)

serializers

Class ASerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
         model = A
         fields = '__all__'
         lookup_field = 'slug'
         extra_kwargs = {'url': {'lookup_field': 'slug'}}


Class BSerializer(serializers.ModelSerializer):
    class Meta:
         model = B
         fields = '__all__'

model viewset

from rest_framework import viewsets, permissions
from rest_framework.response import Response
from rest_framework.decorators import action
from .models import (A, B)
from .serializers import (ASerializer, BSerializer)


Class AViewSet(viewsets.ModelViewSet):
     queryset = A.objects.all()
     serializer_class = ASerializer
     permission_classes =                           (permissions.DjangoModelPermissionsOrAnonReadOnly, )
     lookup_field = 'slug'

     def retrieve(self, request, *args, **kwargs):
          instance = self.get_object()
          bs = B.objects.filter(A=instance.id)
          serializer = BSerializer(bs, many=True)

          return Response(serializer.data)

I want to access a url something like

Url: ^A/<slug>/B/slug>/$

I go through Django Restframework documention and found that we can add custom url like ( drf-custom-rounting. I don't get how to make access url pattern above.

How to customize like that?

EDIT: I have solved my problem. I found a similar type of problem solution here. Thank you for all your response.

2 Answers 2

4

I think what you are looking for is a way to make nested urls.

Recommanded way by DRF doc is using this package : https://github.com/alanjds/drf-nested-routers

Usage example :

First you create your viewset :

Class BViewSet(viewsets.ModelViewSet):
     queryset = B.objects.all()
     serializer_class = BSerializer
     lookup_field = 'slug'

     def retrieve(self, request, a_slug=None, b_slug=None):
          a = self.get_object()
          # Now you retrieve all B related to A
          bs = B.objects.filter(A=a)
          serializer = BSerializer(bs, many=True)
          return Response(serializer.data)

Then you register your viewset using drf-nested-routers :

from rest_framework_nested import routers

from .viewsets import AViewSet, BViewSet

a_router = routers.SimpleRouter()
a_router.register(r'A', AViewSet)

b_router = routers.NestedSimpleRouter(a_router, r'B')
b_router.register(r'B', BViewSet)

urlpatterns = patterns('',
    url(r'^', include(a_router.urls)),
    url(r'^', include(b_router.urls)),
)
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much @Brunoop. I was actually looking samething like this.
0

On your urls.py

from django.conf.urls import url, include
from rest_framework import routers

router = routers.DefaultRouter()
router.register(r'yourregex', views.AViewSet)

urlpatterns = [
    url(r'^api/', include(router.urls)),
]

1 Comment

Hello @Diego Vinicius, thank you for your response. I think you don't get my question. I have already registered my viewset url root, as like /api/A. By default it is providing list, create, retrieve update etc. what i want, i want to customize my retrieve functionality based on url. say if api/A/<slug> provide then it will return the information regarding A, if api/A/<slug>/B/<slug> provide then it will provide information regarding B.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.