Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Implementing Product Details and User Favorites in Django REST Framework

Tech May 10 5

Using ViewSets for Product Detail API

Enable product detail retrieval by adding mixins.RetrieveModelMixin to the viewset:

class ProductListViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):

Product Image Serilaization

For product images, use nested serialization to handle foreign key relationships:

class ProductImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProductImage
        fields = ("image",)

class ProductSerializer(serializers.ModelSerializer):
    category = CategorySerializer()
    images = ProductImageSerializer(many=True)
    
    class Meta:
        model = Product
        fields = '__all__'

Hot Products Filter Implementation

Add is_hot to the filter fields in the filter class:

class ProductFilter(django_filters.FilterSet):
    class Meta:
        model = Product
        fields = ['price_min', 'price_max', 'is_hot']

Set is_hot=True in the admin interface to display products as hot items.

User Favorites API Implementation

Serializer Configuration

from rest_framework import serializers
from user_operations.models import UserFavorite
from rest_framework.validators import UniqueTogetherValidator

class UserFavoriteSerializer(serializers.ModelSerializer):
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )
    
    class Meta:
        validators = [
            UniqueTogetherValidator(
                queryset=UserFavorite.objects.all(),
                fields=('user', 'product'),
                message="Already favorited"
            )
        ]
        model = UserFavorite
        fields = ("user", "product", 'id')

The validator ensures users can only favorite a product once.

ViewSet Implementation

from rest_framework import viewsets, mixins
from user_operations.models import UserFavorite
from user_operations.serializers import UserFavoriteSerializer

class UserFavoriteViewSet(viewsets.GenericViewSet, 
                         mixins.ListModelMixin, 
                         mixins.CreateModelMixin, 
                         mixins.DestroyModelMixin):
    serializer_class = UserFavoriteSerializer
    
    def get_queryset(self):
        return UserFavorite.objects.filter(user=self.request.user)
  • CreateModelMixin: Add favorites
  • DestroyModelMixin: Remove favorites
  • ListModelMixin: Retrieve favorited products

URL Configuration

from user_operations.views import UserFavoriteViewSet

router.register(r'userfavorites', UserFavoriteViewSet, basename="userfavorites")

Permission and Authentication

Custom Permission Class

from rest_framework import permissions

class IsOwnerOrReadOnly(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        if request.method in permissions.SAFE_METHODS:
            return True
        return obj.user == request.user

Enhanced ViewSet with Security

class UserFavoriteViewSet(viewsets.GenericViewSet, 
                         mixins.ListModelMixin, 
                         mixins.CreateModelMixin, 
                         mixins.DestroyModelMixin):
    serializer_class = UserFavoriteSerializer
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
    lookup_field = 'product_id'
    
    def get_queryset(self):
        return UserFavorite.objects.filter(user=self.request.user)

Key configurations:

  • permission_classes: Restrict access to authenticated users
  • authentication_classes: Support JWT and session authentication
  • lookup_field: Use product_id for object lookup
  • get_queryset(): Filter results to current user's data

Frontend Integration

Configure API endpoints for frontend operations:

// Add to favorites
export const addFavorite = params => { 
    return axios.post(`${API_BASE}/userfavorites/`, params) 
}

// Remove favorite
export const removeFavorite = productId => { 
    return axios.delete(`${API_BASE}/userfavorites/`+productId+'/') 
}

// Get all favorites
export const getAllFavorites = () => { 
    return axios.get(`${API_BASE}/userfavorites/`) 
}

// Check favorite status
export const checkFavorite = productId => { 
    return axios.get(`${API_BASE}/userfavorites/`+productId+'/') 
}

Frontend components should display "Favorited" status based on API responses and use product IDs for deletion operations.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.