python
46 lines · 1 tab
Priya Sharma
Jan 2026
1 tab
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from blog.models import Post
from .serializers import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
@action(detail=True, methods=['post'])
def publish(self, request, pk=None):
"""Publish a post."""
post = self.get_object()
post.status = 'published'
post.save()
return Response({'status': 'post published'})
@action(detail=True, methods=['post'])
def unpublish(self, request, pk=None):
"""Unpublish a post."""
post = self.get_object()
post.status = 'draft'
post.save()
return Response({'status': 'post unpublished'})
@action(detail=False, methods=['get'])
def recent(self, request):
"""Get recent posts."""
recent_posts = Post.objects.filter(
status='published'
).order_by('-published_at')[:10]
serializer = self.get_serializer(recent_posts, many=True)
return Response(serializer.data)
@action(detail=True, methods=['get'])
def stats(self, request, pk=None):
"""Get post statistics."""
post = self.get_object()
return Response({
'views': post.view_count,
'comments': post.comments.count(),
'likes': post.likes.count()
})
1 file · python
Explain with highlit
Custom actions extend viewsets beyond CRUD operations. I use @action decorator with detail=True/False for object-level or collection-level actions. This creates endpoints like /posts/1/publish/ or /posts/recent/. I specify HTTP methods, permissions, and serializers per action. Actions keep related logic together in one viewset. For complex operations not fitting REST patterns, actions provide flexibility. I use URL name from action for reverse(). This extends APIs naturally without new viewsets.
Related snips
ruby
payload = {
sub: user.id,
iss: 'https://auth.example.com',
aud: 'codesnips-api',
exp: 15.minutes.from_now.to_i,
iat: Time.now.to_i,
JWT issuance and verification without common footguns
jwt
authentication
api
by Kai Nakamura
2 tabs
python
import os
import stat
for root, _dirs, files in os.walk('/etc'):
for name in files:
path = os.path.join(root, name)
Python security audit script for exposed risky filesystem state
python
auditing
host-security
by Kai Nakamura
1 tab
ruby
module Api
module V1
class UsersController < BaseController
def show
user = User.includes(:profile).find(params[:id])
ETags for conditional requests and caching
rails
caching
http-caching
by Alex Kumar
1 tab
python
class Product(models.Model):
name = models.CharField(max_length=200)
slug = models.SlugField(blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
cost = models.DecimalField(max_digits=10, decimal_places=2)
margin = models.DecimalField(max_digits=5, decimal_places=2, blank=True)
Django model signals vs overriding save
django
python
models
by Priya Sharma
2 tabs
graphql
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
createdAt: String!
GraphQL API with Spring Boot
java
graphql
spring-boot
by David Kumar
3 tabs
python
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
Django URL namespacing and reverse lookups
django
python
urls
by Priya Sharma
3 tabs
Share this code
Here's the card — post it anywhere.