Home > Net >  Detail viewset for product in django rest framework
Detail viewset for product in django rest framework

Time:11-26

I need to get just one product object in my VeiwSet based on a given slug, I looked into the docs, but I can't find any solution to this problem. I need to get the slug from the url path aswell, but I don't know how to do it too. Obviously the code below doesn't work.

product/serializers.py

from rest_framework import serializers
from .models import Product

class ProductSerializer(serializers.ModelSerializer):
    image = serializers.ImageField(required=True)
    class Meta:
        model = Product
        fields = ("name", "description", "slug", "id", "price", "stock", "image", "category")

product/views.py

from django.http.response import JsonResponse
from rest_framework import serializers, viewsets
from rest_framework.response import Response
from django.http import JsonResponse
from .serializers import ProductSerializer
from .models import Product

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all().order_by('name')
    serializer_class = ProductSerializer

class ProductDetailViewSet(viewsets.ViewSet, slug):
    queryset = Product.objects.filter(slug=slug)
    serializer_class = ProductSerializer

product/urls.py

from rest_framework import routers, urlpatterns
from django.urls import path, include
from .views import ProductViewSet, ProductDetailiewSet

router = routers.DefaultRouter()
router.register(r'', ProductViewSet)


urlpatterns = [
    path('<str:slug>/',),
    path('', include(router.urls))
]

CodePudding user response:

ViewSets allows you to combine ListView and DetailView into one view. So you don't need two different views to handle the both actions.

Now if you want to use slug in the url instead of the id by default, you just have to specify lookup_field in the serializer and the view like this :

serializers.py

class ProductSerializer(serializers.ModelSerializer):
    image = serializers.ImageField(required=True)
    class Meta:
        model = Product
        fields = ("name", "description", "slug", "id", "price", "stock", "image", "category")
        lookup_field = 'slug'
        extra_kwargs = {
            'url': {'lookup_field': 'slug'}
        }

views.py

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all().order_by('name')
    serializer_class = ProductSerializer
    lookup_field = 'slug'

urls.py

router = routers.DefaultRouter()
router.register(r'', ProductViewSet)

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

Now you can query http://localhost:8000/ for products list and http://localhost:8000/product_slug for product detail with product_slug as slug. More about Django ViewSets and Routers

  • Related