Django architecture patterns including DRF, ORM optimization, signals, middleware, and project structure
64
76%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./skills/django-patterns/SKILL.mdOrganize Django projects with a clear separation between apps, shared utilities, and configuration.
project/
config/
settings/
base.py
local.py
production.py
urls.py
wsgi.py
apps/
users/
models.py
serializers.py
views.py
services.py
selectors.py
urls.py
tests/
orders/
...
common/
models.py
permissions.py
pagination.pyKeep business logic in services.py (write operations) and selectors.py (read operations). Views should remain thin.
# select_related for ForeignKey / OneToOne (SQL JOIN)
orders = Order.objects.select_related("customer", "customer__profile").all()
# prefetch_related for ManyToMany / reverse FK (separate query)
authors = Author.objects.prefetch_related(
Prefetch("books", queryset=Book.objects.filter(published=True))
).all()
# Defer fields you don't need
posts = Post.objects.defer("body", "metadata").filter(status="published")
# Use .only() when you need just a few columns
emails = User.objects.only("id", "email").filter(is_active=True)
# Bulk operations
Product.objects.bulk_create(products, batch_size=1000)
Product.objects.bulk_update(products, ["price", "stock"], batch_size=1000)Always check queries with django-debug-toolbar or connection.queries in tests.
class OrderSerializer(serializers.ModelSerializer):
customer_name = serializers.CharField(source="customer.full_name", read_only=True)
items = OrderItemSerializer(many=True, read_only=True)
total = serializers.SerializerMethodField()
class Meta:
model = Order
fields = ["id", "customer_name", "items", "total", "created_at"]
read_only_fields = ["id", "created_at"]
def get_total(self, obj):
return sum(item.price * item.quantity for item in obj.items.all())
def validate(self, data):
if data.get("start_date") and data.get("end_date"):
if data["start_date"] >= data["end_date"]:
raise serializers.ValidationError("end_date must be after start_date")
return datafrom django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=Order)
def order_created_handler(sender, instance, created, **kwargs):
if created:
send_order_confirmation.delay(instance.id)
update_inventory.delay(instance.id)Prefer signals for cross-app side effects. For same-app logic, call services directly.
import time
import logging
logger = logging.getLogger(__name__)
class RequestTimingMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
start = time.monotonic()
response = self.get_response(request)
duration = time.monotonic() - start
logger.info(f"{request.method} {request.path} {response.status_code} {duration:.3f}s")
return responseModel.objects.all() without pagination in list endpointsselect_related / prefetch_relatedsettings.py instead of environment variablesselect_related or prefetch_related where neededvalidate methodsebdf1d5
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.