开发编程
#api
django-patterns
Patrones de arquitectura Django, diseño de API REST con DRF, buenas prácticas de ORM, caché, señales, middleware y aplicaciones Django de nivel producción.
DeepseekModel
官方收录技能
质量 优秀 · 90
v1.0.0
获取
https://deepseekmodel.com/api/download.php?id=affaan-m-ecc-docs-es-skills-django-patterns-skill-md&format=skill
下载 .skill
标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用
.skill 文件中 system_prompt 字段的实际内容。
name django-patterns description Patrones de arquitectura Django, diseño de API REST con DRF, buenas prácticas de ORM, caché, señales, middleware y aplicaciones Django de nivel producción. origin ECC Patrones de Desarrollo Django Patrones de arquitectura Django de nivel producción para aplicaciones escalables y mantenibles. Cuándo Activar Construir aplicaciones web Django Diseñar APIs con Django REST Framework Trabajar con el ORM de Django y modelos Configurar la estructura del proyecto Django Implementar caché, señales, middleware Estructura del Proyecto Layout Recomendado myproject/ ├── config/ │ ├── __init__.py │ ├── settings/ │ │ ├── __init__.py │ │ ├── base.py # Configuración base │ │ ├── development.py # Configuración de desarrollo │ │ ├── production.py # Configuración de producción │ │ └── test.py # Configuración de pruebas │ ├── urls.py │ ├── wsgi.py │ └── asgi.py ├── manage.py └── apps/ ├── __init__.py ├── users/ │ ├── __init__.py │ ├── models.py │ ├── views.py │ ├── serializers.py │ ├── urls.py │ ├── permissions.py │ ├── filters.py │ ├── services.py │ └── tests/ └── products/ └── ... Patrón de Configuración Dividida # config/settings/base.py from pathlib import Path BASE_DIR = Path(__file__).resolve().parent.parent.parent SECRET_KEY = env( 'DJANGO_SECRET_KEY' ) DEBUG = False ALLOWED_HOSTS = [] INSTALLED_APPS = [ 'django.contrib.admin' , 'django.contrib.auth' , 'django.contrib.contenttypes' , 'django.contrib.sessions' , 'django.contrib.messages' , 'django.contrib.staticfiles' , 'rest_framework' , 'rest_framework.authtoken' , 'corsheaders' , # Apps locales 'apps.users' , 'apps.products' , ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware' , 'whitenoise.middleware.WhiteNoiseMiddleware' , 'django.contrib.sessions.middleware.SessionMiddleware' , 'corsheaders.middleware.CorsMiddleware' , 'django.middleware.common.CommonMiddleware' , 'django.middleware.csrf.CsrfViewMiddleware' , 'django.contrib.auth.middleware.AuthenticationMiddleware' , 'django.contrib.messages.middleware.MessageMiddleware' , 'django.middleware.clickjacking.XFrameOptionsMiddleware' , ] ROOT_URLCONF = 'config.urls' WSGI_APPLICATION = 'config.wsgi.application' DATABASES = { 'default' : { 'ENGINE' : 'django.db.backends.postgresql' , 'NAME' : env( 'DB_NAME' ), 'USER' : env( 'DB_USER' ), 'PASSWORD' : env( 'DB_PASSWORD' ), 'HOST' : env( 'DB_HOST' ), 'PORT' : env( 'DB_PORT' , default= '5432' ), } } # config/settings/development.py from .base import * DEBUG = True ALLOWED_HOSTS = [ 'localhost' , '127.0.0.1' ] DATABASES[ 'default' ][ 'NAME' ] = 'myproject_dev' INSTALLED_APPS += [ 'debug_toolbar' ] MIDDLEWARE += [ 'debug_toolbar.middleware.DebugToolbarMiddleware' ] EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # config/settings/production.py from .base import * DEBUG = False ALLOWED_HOSTS = env. list ( 'ALLOWED_HOSTS' ) SECURE_SSL_REDIRECT = True SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True SECURE_HSTS_SECONDS = 31536000 SECURE_HSTS_INCLUDE_SUBDOMAINS = True SECURE_HSTS_PRELOAD = True # Logging LOGGING = { 'version' : 1 , 'disable_existing_loggers' : False , 'handlers' : { 'file' : { 'level' : 'WARNING' , 'class' : 'logging.FileHandler' , 'filename' : '/var/log/django/django.log' , }, }, 'loggers' : { 'django' : { 'handlers' : [ 'file' ], 'level' : 'WARNING' , 'propagate' : True , }, }, } Patrones de Diseño de Modelos Buenas Prácticas de Modelos from django.db import models from django.contrib.auth.models import AbstractUser from django.core.validators import MinValueValidator, MaxValueValidator class User ( AbstractUser ): """Modelo de usuario personalizado que extiende AbstractUser.""" email = models.EmailField(unique= True ) phone = models.CharField(max_length= 20 , blank= True ) birth_date = models.DateField(null= True , blank= True ) USERNAME_FIELD = 'email' REQUIRED_FIELDS = [ 'username' ] class Meta : db_table = 'users' verbose_name = 'user' verbose_name_plural = 'users' ordering = [ '-date_joined' ] def __str__ ( self ): return self .email def get_full_name ( self ): return f" {self.first_name} {self.last_name} " .strip() class Product (models.Model): """Modelo de producto con configuración de campos apropiada.""" name = models.CharField(max_length= 200 ) slug = models.SlugField(unique= True , max_length= 250 ) description = models.TextField(blank= True ) price = models.DecimalField( max_digits= 10 , decimal_places= 2 , validators=[MinValueValidator( 0 )] ) stock = models.PositiveIntegerField(default= 0 ) is_active = models.BooleanField(default= True ) category = models.ForeignKey( 'Category' , on_delete=models.CASCADE, related_name= 'products' ) tags = models.ManyToManyField( 'Tag' , blank= True , related_name= 'products' ) created_at = models.DateTimeField(auto_now_add= True ) updated_at = models.DateTimeField(auto_now= True ) class Meta : db_table = 'products' ordering = [ '-created_at' ] indexes = [ models.Index(fields=[ 'slug' ]), models.Index(fields=[ '-created_at' ]), models.Index(fields=[ 'category' , 'is_active' ]), ] constraints = [ models.CheckConstraint( check=models.Q(price__gte= 0 ), name= 'price_non_negative' ) ] def __str__ ( self ): return self .name def save ( self, *args, **kwargs ): if not self .slug: self .slug = slugify( self .name) super ().save(*args, **kwargs) Buenas Prácticas de QuerySet from django.db import models class ProductQuerySet (models.QuerySet): """QuerySet personalizado para el modelo Product.""" def active ( self ): """Retornar solo productos activos.""" return self . filter (is_active= True ) def with_category ( self ): """Seleccionar categoría relacionada para evitar consultas N+1.""" return self .select_related( 'category' ) def with_tags ( self ): """Prefetch tags para relación muchos-a-muchos.""" return self .prefetch_related( 'tags' ) def in_stock ( self ): """Retornar productos con stock > 0.""" return self . filter (stock__gt= 0 ) def search ( self, query ): """Buscar productos por nombre o descripción.""" return self . filter ( models.Q(name__icontains=query) | models.Q(description__icontains=query) ) class Product (models.Model): # ... campos ... objects = ProductQuerySet.as_manager() # Usar QuerySet personalizado # Uso Product.objects.active().with_category().in_stock() Métodos de Manager class ProductManager (models.Manager): """Manager personalizado para consultas complejas.""" def get_or_none ( self, **kwargs ): """Retornar objeto o None en lugar de DoesNotExist.""" try : return self .get(**kwargs) except self .model.DoesNotExist: return None def create_with_tags ( self, name, price, tag_names ): """Crear producto con tags asociados.""" product = self .create(name=name, price=price) tags = [Tag.objects.get_or_create(name=name)[ 0 ] for name in tag_names] product.tags. set (tags) return product def bulk_update_stock ( self, product_ids, quantity ): """Actualización masiva de stock para múltiples productos.""" return self . filter (id__in=product_ids).update(stock=quantity) # En el modelo class Product (models.Model): # ... campos ... custom = ProductManager() Patrones de Django REST Framework Patrones de Serializer from rest_framework import serializers from django.contrib.auth.password_validation import validate_password from .models import Product, User class ProductSerializer (serializers.ModelSerializer): """Serializer para el modelo Product.""" category_name = serializers.CharField(source= 'category.name' , read_only= True ) average_rating = serializers.FloatField(read_only= True ) discount_price = serializers.SerializerMethodField() class Meta : model = Product fields = [ 'id' , 'name' , 'slug' , 'description' , 'price' , 'discount_price' , 'stock' , 'category_name' , 'average_rating' , 'created_at' ] read_only_fields = [ 'id' , 'slug' , 'created_at' ] def get_discount_price ( self, obj ): """Calcular precio con descuento si aplica.""" if hasattr (obj, 'discount' ) and obj.discount: return obj.price * ( 1 - obj.discount.percent / 100 ) return obj.price def validate_price ( self, value ): """Asegurar que el precio no sea negativo.""" if value < 0 : raise serializers.ValidationError( "Price cannot be negative." ) return value class ProductCreateSerializer (serializers.ModelSerializer): """Serializer para crear productos.""" class Meta : model = Product fields = [ 'name' , 'description' , 'price' , 'stock' , 'category' ] def validate ( self, data ): """Validación personalizada para múltiples campos.""" if data[ 'price' ] > 10000 and data[ 'stock' ] > 100 : raise serializers.ValidationError( "Cannot have high-value products with large stock." ) return data class UserRegistrationSerializer (serializers.ModelSerializer): """Serializer para registro de usuario.""" password = serializers.CharField( write_only= True , required= True , validators=[validate_password], style={ 'input_type' : 'password' } ) password_confirm = serializers.CharField(write_only= True , style={ 'input_type' : 'password' }) class Meta : model = User fields = [ 'email' , 'username' , 'password' , 'password_confirm' ] def validate ( self, data ): """Validar que las contraseñas coincidan.""" if data[ 'password' ] != data[ 'password_confirm' ]: raise serializers.ValidationError({ "password_confirm" : "Password fields didn't match." }) return data def create ( self, validated_data ): """Crear usuario con contraseña hasheada.""" validated_data.pop( 'password_confirm' ) password = validated_data.pop( 'password' ) user = User.objects.create(**validated_data) user.set_password(password) user.save() return user Patrones de ViewSet from rest_framework import viewsets, status, filters from rest_framework.decorators import action from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated, IsAdminUser from django_filters.rest_framework import DjangoFilterBackend from .models import Product from .serializers import ProductSerializer, ProductCreateSerializer from .permissions import IsOwnerOrReadOnly from .filters import ProductFilter from .services import ProductService class ProductViewSet (viewsets.ModelViewSet): """ViewSet para el modelo Product.""" queryset = Product.objects.select_related( 'category' ).prefetch_related( 'tags' ) permission_classes = [IsAuthenticated, IsOwnerOrReadOnly] filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter] filterset_class = ProductFilter search_fields = [ 'name' , 'description' ] ordering_fields = [ 'price' , 'created_at' , 'name' ] ordering = [ '-created_at' ] def get_serializer_class ( self ): """Retornar serializer apropiado según la acción.""" if self .action == 'create' : return ProductCreateSerializer return ProductSerializer def perform_create ( self, serializer ): """Guardar con contexto de usuario.""" serializer.save(created_by= self .request.user) @action( detail= False , methods=[ 'get' ] ) def featured ( self, request ): """Retornar productos destacados.""" featured = self .queryset. filter (is_featured= True )[: 10 ] serializer = self .get_serializer(featured, many= True ) return Response(serializer.data)
Agent 识别该技能的关键词,点击任意一个即可复制。
该技能未提供触发词。
下载的 .skill 包内含以下字段。
| 字段 | 说明 |
|---|---|
| format | 格式标识(skill/v1) |
| skill_id | 技能唯一 ID |
| name | 技能名称 |
| version | 版本号 |
| description | 技能描述 |
| category | 所属分类(数组) |
| trigger_words | 触发词列表 |
| tags | 标签列表 |
| source | 来源标识 |
| source_url | 来源链接(本页地址) |
| exported_at | 导出时间(每次下载生成) |
| system_prompt | 系统提示词正文 |
| model_config | 模型参数:provider / model / temperature / max_tokens / top_p |
| examples | 示例 |
| install_guide | 各平台导入说明(Coze / Dify / Claude / 自定义框架) |