django-patterns
Django architecture patterns, REST API design with DRF, ORM best practices, caching, signals, middleware, and production-grade Django apps.
DeepseekModel
キュレーション済みスキル
品質 優秀 · 90
v1.0.0
取得
https://deepseekmodel.com/api/download.php?id=affaan-m-ecc-docs-ja-jp-skills-django-patterns-skill-md&format=skill
ダウンロード .skill
標準形式。system_prompt と model_config を収録し、任意の Agent で利用可能
.skill ファイルの system_prompt フィールドの実際の内容。
name django-patterns description Django architecture patterns, REST API design with DRF, ORM best practices, caching, signals, middleware, and production-grade Django apps. Django 開発パターン スケーラブルで保守可能なアプリケーションのための本番グレードのDjangoアーキテクチャパターン。 いつ有効化するか Djangoウェブアプリケーションを構築するとき Django REST Framework APIを設計するとき Django ORMとモデルを扱うとき Djangoプロジェクト構造を設定するとき キャッシング、シグナル、ミドルウェアを実装するとき プロジェクト構造 推奨レイアウト myproject/ ├── config/ │ ├── __init__.py │ ├── settings/ │ │ ├── __init__.py │ │ ├── base.py # 基本設定 │ │ ├── development.py # 開発設定 │ │ ├── production.py # 本番設定 │ │ └── test.py # テスト設定 │ ├── 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/ └── ... 分割設定パターン # 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' , # Local apps '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 = { '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 , }, }, } モデル設計パターン モデルのベストプラクティス from django.db import models from django.contrib.auth.models import AbstractUser from django.core.validators import MinValueValidator, MaxValueValidator class User ( AbstractUser ): """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): """適切なフィールド設定を持つProductモデル。""" 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) QuerySetのベストプラクティス from django.db import models class ProductQuerySet (models.QuerySet): """Productモデルのカスタム QuerySet。""" def active ( self ): """アクティブな製品のみを返す。""" return self . filter (is_active= True ) def with_category ( self ): """N+1クエリを避けるために関連カテゴリを選択。""" return self .select_related( 'category' ) def with_tags ( self ): """多対多リレーションシップのためにタグをプリフェッチ。""" return self .prefetch_related( 'tags' ) def in_stock ( self ): """在庫が0より大きい製品を返す。""" return self . filter (stock__gt= 0 ) def search ( self, query ): """名前または説明で製品を検索。""" return self . filter ( models.Q(name__icontains=query) | models.Q(description__icontains=query) ) class Product (models.Model): # ... フィールド ... objects = ProductQuerySet.as_manager() # カスタムQuerySetを使用 # 使用例 Product.objects.active().with_category().in_stock() マネージャーメソッド class ProductManager (models.Manager): """複雑なクエリ用のカスタムマネージャー。""" def get_or_none ( self, **kwargs ): """DoesNotExistの代わりにオブジェクトまたはNoneを返す。""" try : return self .get(**kwargs) except self .model.DoesNotExist: return None def create_with_tags ( self, name, price, tag_names ): """関連タグを持つ製品を作成。""" 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 ): """複数の製品の在庫を一括更新。""" return self . filter (id__in=product_ids).update(stock=quantity) # モデル内 class Product (models.Model): # ... フィールド ... custom = ProductManager() Django REST Frameworkパターン シリアライザーパターン from rest_framework import serializers from django.contrib.auth.password_validation import validate_password from .models import Product, User class ProductSerializer (serializers.ModelSerializer): """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 ): """該当する場合は割引価格を計算。""" if hasattr (obj, 'discount' ) and obj.discount: return obj.price * ( 1 - obj.discount.percent / 100 ) return obj.price def validate_price ( self, value ): """価格が非負であることを確認。""" if value < 0 : raise serializers.ValidationError( "Price cannot be negative." ) return value class ProductCreateSerializer (serializers.ModelSerializer): """製品作成用のシリアライザー。""" class Meta : model = Product fields = [ 'name' , 'description' , 'price' , 'stock' , 'category' ] def validate ( self, data ): """複数フィールドのカスタム検証。""" 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): """ユーザー登録用のシリアライザー。""" 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 ): """パスワードが一致することを検証。""" if data[ 'password' ] != data[ 'password_confirm' ]: raise serializers.ValidationError({ "password_confirm" : "Password fields didn't match." }) return data def create ( self, validated_data ): """ハッシュ化されたパスワードでユーザーを作成。""" validated_data.pop( 'password_confirm' ) password = validated_data.pop( 'password' ) user = User.objects.create(**validated_data) user.set_password(password) user.save() return user 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): """Productモデル用のViewSet。""" 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 ): """アクションに基づいて適切なシリアライザーを返す。""" if self .action == 'create' : return ProductCreateSerializer return ProductSerializer def perform_create ( self, serializer ): """ユーザーコンテキストで保存。""" serializer.save(created_by= self .request.user) @action( detail= False , methods=[ 'get' ] ) def featured ( self, request ): """注目の製品を返す。""" featured = self .queryset. filter (is_featured= True )[: 10 ] serializer = self .get_serializer(featured, many= True ) return Response(serializer.data) @action( detail= True , methods=[ 'post' ] ) def purchase ( self, request, pk= None ): """製品を購入。""" product = self .get_object()
このスキルを起動するキーワード。クリックでコピーできます。
このスキルにはトリガーワードがありません。
ダウンロードした .skill に含まれるフィールド。
| フィールド | 説明 |
|---|---|
| format | フォーマット識別子(skill/v1) |
| skill_id | スキル固有 ID |
| name | スキル名 |
| version | バージョン |
| description | 説明 |
| category | カテゴリ(配列) |
| trigger_words | トリガーワード |
| tags | タグ |
| source | ソース |
| source_url | ソース URL(本ページ) |
| exported_at | エクスポート日時(ダウンロード毎) |
| system_prompt | システムプロンプト本文 |
| model_config | モデル設定:provider / model / temperature / max_tokens / top_p |
| examples | サンプル |
| install_guide | 各プラットフォームの導入説明(Coze / Dify / Claude / カスタム) |