Skip to content
Back to skills

206 Python 48ce90f1

ASecurity

```python from rest_framework import viewsets, status from rest_framework.decorators import action from rest_framework.response import Response from rest_framework.permissions import IsAuthenticatedOrReadOnly from django_filters.rest_framework import DjangoFilterBackend

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
developmentpythongodjangoapibackend

Works with

  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 206-python_48ce90f1 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 206 Python 48ce90f1?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 206 Python 48ce90f1
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-206-python-48ce90f1/badge)](https://www.skillsdirectory.com/skills/tools-only-206-python-48ce90f1)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# ViewSets & Views

## ModelViewSet

```python
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from django_filters.rest_framework import DjangoFilterBackend

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.select_related('category', 'created_by')
    serializer_class = ProductSerializer
    permission_classes = [IsAuthenticatedOrReadOnly]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['category', 'is_active']
    search_fields = ['name', 'description']
    ordering_fields = ['price', 'created_at']
    lookup_field = 'slug'

    def get_queryset(self):
        qs = super().get_queryset()
        if self.action == 'list':
            return qs.filter(is_active=True)
        return qs

    def perform_create(self, serializer):
        serializer.save(created_by=self.request.user)

    @action(detail=True, methods=['post'])
    def purchase(self, request, slug=None):
        product = self.get_object()
        quantity = request.data.get('quantity', 1)

        if product.stock < quantity:
            return Response(
                {'error': 'Insufficient stock'},
                status=status.HTTP_400_BAD_REQUEST
            )

        product.stock -= quantity
        product.save()
        return Response({'message': 'Purchase successful'})

    @action(detail=False, methods=['get'])
    def featured(self, request):
        featured = self.get_queryset().filter(is_featured=True)[:10]
        serializer = self.get_serializer(featured, many=True)
        return Response(serializer.data)
```

## Django 5.0 Async Views

```python
from django.http import JsonResponse
from asgiref.sync import sync_to_async

# Async function-based view
async def user_list(request):
    users = await sync_to_async(list)(
        User.objects.all()[:100]
    )
    return JsonResponse({'users': [u.to_dict() for u in users]})

# Async class-based view
from django.views import View

class AsyncProductView(View):
    async def get(self, request, product_id):
        product = await sync_to_async(
            Product.objects.select_related('category').get
        )(pk=product_id)
        return JsonResponse({
            'id': product.id,
            'name': product.name,
            'category': product.category.name,
        })
```

## Generic Views

```python
from rest_framework import generics

class ProductListCreate(generics.ListCreateAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    permission_classes = [IsAuthenticatedOrReadOnly]

class ProductDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    lookup_field = 'slug'
```

## URL Configuration

```python
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register('products', ProductViewSet, basename='product')

urlpatterns = [
    path('api/', include(router.urls)),
]

# Generated URLs:
# GET/POST    /api/products/
# GET/PUT/DELETE /api/products/{slug}/
# POST        /api/products/{slug}/purchase/
# GET         /api/products/featured/
```

## Pagination

```python
# settings.py
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 20,
}

# Custom pagination
from rest_framework.pagination import PageNumberPagination

class LargeResultsSetPagination(PageNumberPagination):
    page_size = 100
    page_size_query_param = 'page_size'
    max_page_size = 1000

class ProductViewSet(viewsets.ModelViewSet):
    pagination_class = LargeResultsSetPagination
```

## Quick Reference

| ViewSet Method | HTTP | Action |
|---------------|------|--------|
| `list()` | GET | List all |
| `create()` | POST | Create new |
| `retrieve()` | GET | Get one |
| `update()` | PUT | Full update |
| `partial_update()` | PATCH | Partial update |
| `destroy()` | DELETE | Delete |

| Hook | Purpose |
|------|---------|
| `get_queryset()` | Filter queryset |
| `get_serializer_class()` | Dynamic serializer |
| `perform_create()` | Pre-save logic |
| `@action()` | Custom endpoints |

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.