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.

Shakil
  • 4,520
  • 3
  • 26
  • 36

2 Answers2

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)),
)
Brunoop
  • 178
  • 1
  • 8
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)),
]
Diego Vinícius
  • 2,125
  • 1
  • 12
  • 23
  • 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/ provide then it will return the information regarding A, if api/A//B/ provide then it will provide information regarding B. – Shakil Jul 05 '18 at 05:45