Skip to main content

django-patterns

Django development principles and decision-making. Modern Django 4.2+ with DRF, Celery, Docker.

Informações da origem

Repositório
skeletorflet/opencode-kit
Última atividade na origem
31 de março de 2026 às 19:12
Idioma detectado do SKILL.md
inglês
Estrelas
9
Forks
1

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
django-patterns
description
Django development principles and decision-making. Modern Django 4.2+ with DRF, Celery, Docker.
# Django Patterns - Modern Django 4.2+ > Django development principles and decision-making. > **Learn to THINK, not copy-paste patterns.** --- ## ⚠️ How to Use This Skill This skill teaches **decision-making principles** for Django development. - START: Ask project scale (smallAPI vs enterprise) - CHOOSE: Function-based vs Class-based views - USE: Django REST Framework for APIs - THINK: Django is "batteries included" - use built-in features --- ## 1. Project Structure by Scale ### Small Project ``` myproject/ ├── manage.py ├── myproject/ │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── app/ │ ├── __init__.py │ ├── models.py │ ├── views.py │ ├── urls.py │ └── admin.py ├── requirements.txt └── .env ``` ### Medium Project (Modular) ``` project/ ├── manage.py ├── requirements.txt ├── .env ├── core/ # Project settings │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ ├── wsgi.py │ └── asgi.py ├── apps/ │ ├── users/ │ │ ├── models.py │ │ ├── views.py │ │ ├── serializers.py │ │ ├── urls.py │ │ ├── permissions.py │ │ └── apps.py │ └── products/ ├── services/ # Business logic ├── utils/ # Shared utilities ├── templates/ ├── static/ └── media/ ``` ### Large Project (DDD) ``` project/ ├── core/ ├── apps/ │ ├── users/ │ │ ├── __init__.py │ │ ├── models/ │ │ │ ├── __init__.py │ │ │ └── user.py │ │ ├── repositories/ │ │ ├── services/ │ │ ├── views/ │ │ │ ├── __init__.py │ │ │ ├── api/ │ │ │ └── admin/ │ │ ├── serializers/ │ │ ├── permissions/ │ │ └── tests/ │ └── orders/ ├── domain/ # Domain layer │ ├── entities/ │ ├── value_objects/ │ └── events/ ├── application/ # Application services │ ├── use_cases/ │ └── dtos/ ├── infrastructure/ # DB, External APIs │ ├── persistence/ │ ├── repositories/ │ └── external/ └── presentation/ # Views, APIs, Admin ``` --- ## 2. Models & Database ### Model Patterns ```python # models.py from django.db import models from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin from django.utils import timezone from django.conf import settings class User(AbstractBaseUser, PermissionsMixin): """Custom user model.""" email = models.EmailField(unique=True) username = models.CharField(max_length=150, unique=True) is_staff = models.BooleanField(default=False) is_active = models.BooleanField(default=True) date_joined = models.DateTimeField(default=timezone.now) objects = UserManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['username'] class Meta: db_table = 'users' ordering = ['-date_joined'] def __str__(self): return self.email class TimestampedModel(models.Model): """Abstract base with created/updated timestamps.""" created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: abstract = True ordering = ['-created_at'] class Product(TimestampedModel): """Product model with proper relationships.""" name = models.CharField(max_length=255) slug = models.SlugField(max_length=255, unique=True) description = models.TextField(blank=True) price = models.DecimalField(max_digits=10, decimal_places=2) stock = models.PositiveIntegerField(default=0) is_available = models.BooleanField(default=True) category = models.ForeignKey( 'Category', on_delete=models.SET_NULL, null=True, related_name='products' ) tags = models.ManyToManyField('Tag', blank=True) owner = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='products' ) class Meta: ordering = ['-created_at'] indexes = [ models.Index(fields=['slug']), models.Index(fields=['created_at']), ] def __str__(self): return self.name ``` ### QuerySet Managers ```python class ProductManager(models.Manager): """Custom manager with query methods.""" def available(self): return self.filter(is_available=True) def in_stock(self): return self.filter(stock__gt=0) def by_category(self, category_slug): return self.filter(category__slug=category_slug) def with_price_range(self, min_price, max_price): return self.filter(price__gte=min_price, price__lte=max_price) class Product(models.Model): # ... fields ... objects = ProductManager() ``` --- ## 3. Django REST Framework ### Serializers ```python # serializers.py from rest_framework import serializers from .models import User, Product from django.contrib.auth.password_validation import validate_password class UserSerializer(serializers.ModelSerializer): """Serializer for User model.""" class Meta: model = User fields = ['id', 'email', 'username', 'date_joined'] read_only_fields = ['id', 'date_joined'] class UserCreateSerializer(serializers.ModelSerializer): """Serializer for creating users.""" password = serializers.CharField(write_only=True) password_confirm = serializers.CharField(write_only=True) class Meta: model = User fields = ['email', 'username', 'password', 'password_confirm'] def validate(self, data): if data['password'] != data['password_confirm']: raise serializers.ValidationError({'password_confirm': 'Passwords do not match'}) validate_password(data['password']) return data def create(self, validated_data): validated_data.pop('password_confirm') user = User.objects.create_user(**validated_data) return user class ProductSerializer(serializers.ModelSerializer): """Serializer for Product with nested relationships.""" category_name = serializers.CharField(source='category.name', read_only=True) owner_email = serializers.CharField(source='owner.email', read_only=True) class Meta: model = Product fields = [ 'id', 'name', 'slug', 'description', 'price', 'stock', 'is_available', 'category', 'category_name', 'owner', 'owner_email', 'created_at', 'updated_at' ] read_only_fields = ['id', 'created_at', 'updated_at'] def to_representation(self, instance): # Customize output data = super().to_representation(instance) data['price'] = float(instance.price) return data ``` ### Views ```python # views.py from rest_framework import viewsets, status from rest_framework.decorators import action from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated, IsAdminUser from django.db.models import Q from .models import Product from .serializers import ProductSerializer class ProductViewSet(viewsets.ModelViewSet): """ViewSet for Product with custom actions.""" queryset = Product.objects.select_related('category', 'owner').all() serializer_class = ProductSerializer lookup_field = 'slug' # Filtering filterset_fields = ['category', 'is_available'] search_fields = ['name', 'description'] ordering_fields = ['price', 'created_at'] ordering = ['-created_at'] def get_permissions(self): if self.action in ['list', 'retrieve']: return [] elif self.action in ['create']: return [IsAuthenticated()] elif self.action in ['update', 'partial_update', 'destroy']: return [IsAuthenticated(), IsAdminUser()] return [IsAuthenticated()] def get_queryset(self): queryset = super().get_queryset() # Custom filtering in_stock = self.request.query_params.get('in_stock') if in_stock: queryset = queryset.filter(stock__gt=0) return queryset @action(detail=False, methods=['get']) def cheap(self, request): """Get cheap products under $10.""" cheap_products = self.queryset.filter(price__lt=10) serializer = self.get_serializer(cheap_products, many=True) return Response(serializer.data) @action(detail=True, methods=['post']) def publish(self, request, slug=None): """Publish a product.""" product = self.get_object() product.is_available = True product.save() return Response({'status': 'product published'}) ``` ### URLs ```python # urls.py from django.urls import path, include from rest_framework.routers import DefaultRouter from .views import ProductViewSet router = DefaultRouter() router.register(r'products', ProductViewSet, basename='product') urlpatterns = [ path('', include(router.urls)), ] ``` --- ## 4. Authentication ### JWT Authentication ```python # settings.py REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], } # settings.py - Simple JWT SIMPLE_JWT = { 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60), 'REFRESH_TOKEN_LIFETIME': timedelta(days=1), 'ROTATE_REFRESH_TOKENS': True, 'BLACKLIST_AFTER_ROTATION': True, 'AUTH_HEADER_TYPES': ('Bearer',), } ``` ### Custom Permissions ```python # permissions.py from rest_framework import permissions class IsOwnerOrReadOnly(permissions.BasePermission): """Custom permission: only owners can edit.""" def has_object_permission(self, request, view, obj): if request.method in permissions.SAFE_METHODS: return True return obj.owner == request.user or request.user.is_staff class IsAdminOrReadOnly(permissions.BasePermission): """Only admins can write, everyone can read.""" def has_permission(self, request, view): if request.method in permissions.SAFE_METHODS: return True return request.user and request.user.is_staff ``` --- ## 5. Background Jobs with Celery ```python # tasks.py from celery import shared_task from django.core.mail import send_mail @shared_task def send_order_confirmation(order_id): """Send order confirmation email.""" order = Order.objects.get(id=order_id) send_mail( 'Order Confirmation', f'Your order #{order_id} has been confirmed.', 'noreply@example.com', [order.user.email], fail_silently=False, ) @shared_task def process_order(order_id): """Process order asynchronously.""" from .services import OrderProcessor processor = OrderProcessor(order_id) processor.process() return f'Order {order_id} processed' # Celery configuration # celery.py from celery import Celery app = Celery('project') app.config_from_object('django.conf:settings', namespace='CELERY') app.autodiscover_tasks() app.conf.beat_schedule = { 'delete-expired-orders': { 'task': 'orders.tasks.delete_expired_orders', 'schedule': 86400, # Daily }, } ``` --- ## 6. Testing ### Unit Tests ```python # tests/test_models.py from django.test import TestCase from django.contrib.auth import get_user_model from products.models import Product, Category User = get_user_model() class UserModelTest(TestCase): """Test User model.""" def test_create_user(self): user = User.objects.create_user( username='testuser', email='test@example.com', password='testpass123' ) self.assertEqual(user.email, 'test@example.com') self.assertFalse(user.is_staff) self.assertFalse(user.is_superuser) def test_create_superuser(self):
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub