1

I'm looking for how to make a GET in django swagger framework by refClient (a unique CharField in my client's model). I found on the internet that I have to customize the routers, I have that as routers :

from rest_framework.schemas import get_schema_view
from rest_framework_swagger.renderers import SwaggerUIRenderer, OpenAPIRenderer

schema_view = get_schema_view(
    title='Swagger documentation',
    renderer_classes = [OpenAPIRenderer, SwaggerUIRenderer],
)

# Routers provide an easy way of automatically determining the URL conf.
router = routers.DefaultRouter(trailing_slash=False)
router.register(r'clients/{refClient}', ClientViewSet)

# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # To show the swagger documentation
    url(r'^swagger/', schema_view, name="docs"),
    url(r'^api/v1/', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
   ] 

But I got this error

ValueError: invalid literal for int() with base 10: 'refClient'
[21/Jul/2017 15:25:22] "GET /swagger/ HTTP/1.1" 500 133494

Should I add something to my serializers's configuration

class ClientSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Client
        fields = ('refClient', 'nom', 'prenom')

Or to my views ?

class ClientViewSet(viewsets.ModelViewSet):
    queryset = Client.objects.all()
    serializer_class = ClientSerializer

    def get_queryset(self):
        """ GET : get all clients """
        return Client.objects.all()

    def create(self, request):
       """ POST : Create a Client object """
        return super(ClientViewSet, self).create(request)

    def retrieve(self, request, pk=None):
        """ GET : Returns a single client item """
        return super(ClientViewSet, self).retrieve(request, pk)

    def update(self, request, *args, **kwargs):
        """ PUT : Updates a single client item """
        return super(ClientViewSet, self).update(request, *args, **kwargs)

    def partial_update(self, request, *args, **kwargs):
        """ PATCH : Partiel update a client """
        return super(ClientViewSet, self).partial_update(request, *args, **kwargs)

    def destroy(self, request, pk=None):
        """ DELETE : Delete a client """
        return super(ClientViewSet, self).destroy(request, pk)

Basically how I can customize my swagger ?

Naella
  • 425
  • 2
  • 6
  • 17

1 Answers1

1

By default django rest frameworks uses this lookup_field = 'pk' lookup_url_kwarg = None

You can override this in your ClientViewSet class, change to lookup_field = 'refClient'

However if you want to support both lookups, either by 'pk' or by 'refClient' I suggest to have a different endpoint for the later one (eg. /api/client_url/ref/), or add filtering option in your list view (eg. /api/client_url?refClient='something')

Gabriel Muj
  • 3,682
  • 1
  • 19
  • 28
  • Thank you! that works for me. Have you any idea how can I make complexe routers in django rest swagger ? (For example if my client object contains an articles attribute ManyToMany in the model and I want to have a route like this; client/{refClient}/articles/{refArticle} in the swagger). Thanks – Naella Jul 24 '17 at 08:08
  • I am not a big fan of having nested routers, I would approach this as having a url pattern like this: `client//articles/` pointing to an `ClientArticlesViewSet(ModelViewSet)` in which you will override get_queryset() to filter by from self.kwargs . In this way your endpoint will behave as normal router for articles but with that filter in place. The kwargs should be available in swagger. – Gabriel Muj Jul 24 '17 at 09:20
  • Please can you have a look at the answer below. Thanks – Naella Jul 24 '17 at 11:09
  • Should I add refClient to articles's model? Thanks again – Naella Jul 24 '17 at 11:34
  • I don't see any answer. Maybe you should create a new question for this – Gabriel Muj Jul 24 '17 at 12:02
  • This is exactly what I wanted to do, big thanks but I have a 404 not found Not Found: /api/v1/clients/ref123456/articles [24/Jul/2017 11:50:34] "GET /api/v1/clients/ref123456/articles HTTP/1.1" 404 12629 I may be don't know how to override get_queryset() to filter by from self.kwargs, I just added filter_backends = (DjangoFilterBackend,) filter_fields = ('refArticle',) to my ClientArticlesViewSet – Naella Jul 24 '17 at 12:05
  • I've also tried this : def get_queryset(self): return Articles.objects.filter(self.kwargs) ... But that don't work for me – Naella Jul 24 '17 at 12:12
  • Do you have a FK in Articles model to Client? If so, use that field name to filter by: `def get_queryset(self): return Articles.objects.filter(: self.kwargs['ref'])` where `ref` is the name in the url regex – Gabriel Muj Jul 24 '17 at 12:18
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/149993/discussion-between-muj-gabriel-and-chaysi). – Gabriel Muj Jul 24 '17 at 12:26
  • I sent you a message in the shat, please go to see it – Naella Jul 26 '17 at 12:30