Skip to content

Latest commit

 

History

History
117 lines (94 loc) · 9.77 KB

File metadata and controls

117 lines (94 loc) · 9.77 KB

File Structure and Organization

  • All Django apps must live in apps/ directory. No top-level app folders. Structure: apps/{app_name}/models.py, apps/{app_name}/views.py, apps/{app_name}/serializers.py, apps/{app_name}/services.py, apps/{app_name}/tests/.
  • Business logic must live in apps/{app_name}/services.py. Views import and call service functions. Never write business logic in views.py.
  • All database queries must live in apps/{app_name}/models.py as custom managers or in services.py. Never write .filter() or .get() directly in views.
  • Test files must be in apps/{app_name}/tests/ with naming: test_models.py, test_views.py, test_services.py, test_serializers.py. Never put tests in a single tests.py file.
  • Serializers must be in apps/{app_name}/serializers.py. Never define serializers in views.py or models.py.
  • URL routing must be in apps/{app_name}/urls.py. Never define URL patterns in views.py.
  • Constants and enums must be in apps/{app_name}/constants.py. Never hardcode strings or numbers in views, serializers, or services.
  • All HTTP responses must use DRF Response class with explicit status codes. Never return Django HttpResponse.

Naming Conventions

  • Model names must be singular: User, BlogPost, OrderItem. Never Users or BlogPosts.
  • Serializer names must end with Serializer: UserSerializer, BlogPostDetailSerializer, OrderItemCreateSerializer.
  • Service function names must be verbs: create_user(), update_order_status(), send_notification_email(). Never user_creation() or order_status_update().
  • View class names must end with View or ViewSet: UserListView, BlogPostViewSet. Never UserAPI or BlogPostHandler.
  • Manager method names must be descriptive: active_users(), recent_posts(), pending_orders(). Never get_all() or filter_data().
  • Variable names must be explicit: user_email, order_total, is_active. Never u, o, x, or data.
  • Boolean variables must start with is_ or has_: is_verified, has_permission, is_deleted. Never active or verified alone.

Database Query Rules

  • Every QuerySet must have .select_related() or .prefetch_related() if accessing foreign keys or reverse relations. Verify with Django Debug Toolbar or django-silk. Never use bare .all() or .filter() on related fields.
  • Every list endpoint must use pagination. Use rest_framework.pagination.PageNumberPagination with page_size=20. Never return unbounded QuerySets.
  • Every QuerySet must use .only() or .defer() to limit fields fetched. Never use SELECT * implicitly. Example: User.objects.only('id', 'email', 'name').
  • Raw SQL queries are forbidden. Use ORM exclusively. If ORM is insufficient, use .raw() with parameterized queries only and document why in a comment.
  • .count() must be called on filtered QuerySets only. Never call .count() on objects.all() without filters.
  • Bulk operations must use .bulk_create() or .bulk_update() for 10+ objects. Never loop and .save().
  • All QuerySets must be evaluated in views or services, never in templates. Pass evaluated data to serializers.

Serializer Rules

  • Serializers must validate all input. Use validate_field_name() methods for field-level validation and validate() for cross-field validation.
  • Serializers must never directly call .save() on model instances. Use create() and update() methods explicitly.
  • Serializers must use read_only_fields for computed or auto-generated fields: id, created_at, updated_at.
  • Serializers must use required=False only with explicit allow_blank=True or allow_null=True. Never use required=False without justification.
  • Nested serializers must use many=True for lists. Never return raw model instances in nested fields.
  • Serializers must use source parameter to map model fields to API fields. Example: source='user.email' for nested access.
  • Serializers must define Meta.fields explicitly. Never use fields = '__all__'.

View and ViewSet Rules

  • All views must inherit from DRF classes: APIView, ViewSet, ModelViewSet. Never use Django's generic View.
  • Views must use permission_classes decorator or class attribute. Never skip permission checks. Example: @permission_classes([IsAuthenticated]).
  • Views must use authentication_classes explicitly. Never rely on default settings.
  • Views must return DRF Response with explicit status code. Never return JsonResponse or HttpResponse.
  • ViewSets must define queryset and serializer_class as class attributes. Never define them in __init__().
  • ViewSets must override get_queryset() to apply user-specific filters. Never use class-level queryset for user-dependent data.
  • Views must use get_object_or_404() from django.shortcuts. Never use .get() without exception handling.
  • Views must call service functions, never write business logic inline. Example: user = create_user_service(validated_data).

Service Layer Rules

  • All service functions must accept only primitives or serializer-validated data, never raw request objects.
  • Service functions must raise custom exceptions, never return error tuples or None. Define exceptions in apps/{app_name}/exceptions.py.
  • Service functions must be pure or have documented side effects (email, external API calls). Add # Side effect: sends email comment.
  • Service functions must log all state changes at INFO level. Use logger.info(f"User {user_id} created").
  • Service functions must not import views or serializers. Dependency flow: views → services → models.
  • Service functions must use transactions for multi-step operations: from django.db import transaction; @transaction.atomic.

Error Handling

  • All exceptions must be custom classes inheriting from Exception or DRF.exceptions.APIException. Define in apps/{app_name}/exceptions.py.
  • All service functions must raise exceptions with context: raise UserNotFoundError(f"User {user_id} not found"). Never raise generic Exception.
  • All views must catch service exceptions and return appropriate HTTP status. Use DRF exception handlers.
  • All database operations must handle IntegrityError and ObjectDoesNotExist explicitly. Never let them bubble up.
  • All external API calls must have try/except with timeout handling. Set timeout to 5 seconds maximum.
  • All form/serializer validation errors must be caught and returned as 400 with field-level error messages.

Logging and Debugging

  • Never use print(). Use import logging; logger = logging.getLogger(__name__) in every module.
  • Log levels: logger.debug() for variable inspection, logger.info() for state changes, logger.warning() for recoverable issues, logger.error() for exceptions.
  • All service function entry/exit must be logged at DEBUG level: logger.debug(f"create_user called with email={email}").
  • All exceptions must be logged with logger.exception() in exception handlers, never logger.error().
  • Never log sensitive data: passwords, tokens, API keys, SSNs, credit cards. Use *** masking.

Security Rules

  • All environment variables must be loaded via python-decouple or django-environ. Never hardcode secrets.
  • All user input must be validated at serializer level before reaching services. Never trust request.data directly.
  • All QuerySets filtering by user must use request.user. Never accept user_id as a parameter without verification.
  • All file uploads must validate MIME type and size. Use django-storages for S3 uploads, never local filesystem.
  • All API endpoints must have rate limiting. Use django-ratelimit or DRF throttling. Set to 100 requests/hour minimum.
  • All SQL queries must use parameterized queries. Never use string formatting for WHERE clauses.
  • All CORS headers must be explicit. Use django-cors-headers with CORS_ALLOWED_ORIGINS whitelist, never CORS_ALLOW_ALL_ORIGINS = True.

Testing Rules

  • All models must have unit tests in apps/{app_name}/tests/test_models.py. Test custom managers and properties.
  • All services must have unit tests in apps/{app_name}/tests/test_services.py. Mock external dependencies.
  • All views must have integration tests in apps/{app_name}/tests/test_views.py. Use APITestCase and APIClient.
  • All serializers must have tests in apps/{app_name}/tests/test_serializers.py. Test validation and field mapping.
  • All tests must use fixtures or factories. Use factory-boy for model creation. Never hardcode test data.
  • All tests must have descriptive names: test_create_user_with_valid_email_succeeds(). Never test_user() or test_1().
  • All tests must assert both success and failure cases. Never test only the happy path.
  • Test coverage must be minimum 80% for services and models. Use coverage.py and check in CI.

Forbidden Patterns

  • Never use objects.all() without pagination in views. Always paginate list endpoints.
  • Never use @csrf_exempt. Always use CSRF protection for POST/PUT/DELETE.
  • Never use request.POST or request.GET directly. Always use serializers for validation.
  • Never use eval() or exec(). Never use pickle for untrusted data.
  • Never use datetime.now() for comparisons. Use timezone.now() from django.utils.timezone.
  • Never use Model.objects.create() in views. Always use service functions.
  • Never use **kwargs in function signatures without documenting expected keys. Be explicit.
  • Never use from django.conf import settings at module level. Import inside functions if needed.
  • Never commit database transactions manually. Use @transaction.atomic decorator.
  • Never use get_user_model() in model definitions. Use settings.AUTH_USER_MODEL as string reference.

Source: Codelibrium — the marketplace for AI behaviour files. Browse multiple rulesets at codelibrium.com or install via CLI: npx codelibrium-cli install <ruleset-name>