Search code examples
djangorestdjango-rest-frameworkapi-design

How to organize Django REST Framework urls


I am working on some dummy e-commerce application in Django (DRF) and I am a bit confused how to write good REST API's.

Models

class Category(models.Model):
    name = models.Char...

class Product(models.Model):
    category = models.ForeignKey(...)
    name = models.Char...

Views

class ProductListView(APIView):
    def get(self, request, category_slug=None):
        products = Product.objects.filter(available=True)
        if category_slug:
            category = get_object_or_404(Category, slug=category_slug)
            products = products.filter(category=category)
        serializer = ProductSerializer(products, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)
First Question

So my question is if I should put logic for filtering with capture value (categori_slug) in this view or would it be more clear if I create two endpoints?

Second Question

In DRF is bottom code good practice to send multiple data trough result/endpoint?

return Response({data: serializer.data, other_data: serializer_other.data}, status=st...)

So as I am learning all the time only one serializer.data is passed trough one Response API but what if I want that client can also access some other data. Is better to split it in multiple views and than let client make multiple requests?

PS: This is my first Stack Overflow question so I would appreciate some feedback on this as well.


Solution

  • (First question) I think either of the approach is okay. If you want to use one end point for products (with or without the category), then you should implement like this:

    class ProductListView(APIView):
        def get(self, request):
            products = Product.objects.filter(available=True)
            category_slug = request.GET.get('category', None)
            if category_slug:
                products = products.filter(category__slug=category_slug)
            serializer = ProductSerializer(products, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)
    

    Then you need to call the api like this: http://localhost:8000/products/?category_slug=XXXX.

    (Second question) For the data part, I think one view or one url should return one kind of data. Thus product url should return product data. If client has to call multiple apis to get multiple kinds of data, that sounds okay to me.