К основному содержанию
правило

django — правило для Cursor: что делает и как установить

Правило задаёт структуру проекта, организацию кода и паттерны безопасности для Django-приложений в Cursor.

Установить в Cursor · Вручную: положить файлы Все способы и платформы ↓
.cursor/rules/django.mdc
Открыть на GitHub

Что делает django

Правило описывает src-layout с разделением настроек на base, development и production, хранение секретов через django-environ, именование моделей в единственном числе и related_name во множественном. Бизнес-логика выносится в методы модели или сервисный слой, а не во вью. Для борьбы с N+1 используются select_related и prefetch_related, для частых фильтров — db_index=True. В блокирующих ORM-вызовах внутри async-вью применяется sync_to_async.

В разделе безопасности правило требует permission_classes из Django REST Framework вместо ручных проверок во вью, ManifestStaticFilesStorage для статики и облачное хранилище для медиа в продакшене. Для CRUD рекомендуются ModelViewSet и роутеры DRF. Без django-environ и правильного разделения файлов настроек секреты попадут в репозиторий.

Какие задачи решает

  • выстроить структуру Django-проекта с разделением настроек на окружения
  • убрать N+1 запросы через select_related и prefetch_related
  • вынести бизнес-логику из вью в модели или сервисы
  • добавить индексы на часто фильтруемые поля
  • настроить role-based permissions в Django REST Framework

Примеры запросов агенту

  • Покажи, как разбить settings.py на base, development и production с django-environ
  • Перепиши этот вью так, чтобы логика создания заказа ушла в модель Order
  • Оптимизируй запрос списка книг с авторами — сейчас N+1

Как установить django

Вручную: положить файлы

.cursor/rules/django.mdc

Во frontmatter: description, globs, alwaysApply

По шагам, с командами для каждой платформы: Cursor rules: файлы .mdc, четыре режима и замена .cursorrules

Вопросы о django

Как установить правило django в Cursor?

Положите файл в .cursor/rules/django.mdc — Cursor подхватит его автоматически для всех файлов .py в проекте.

Что делает правило django?

Задаёт структуру проекта с src-layout, разделение настроек по окружениям, именование моделей, паттерны вынесения логики из вью, оптимизацию ORM-запросов и настройку безопасности через permission_classes в DRF.

Зачем нужен django-environ?

Библиотека считывает секреты и параметры окружения из .env, чтобы они не попадали в репозиторий. В правиле это обязательное требование для хранения SECRET_KEY, DATABASE_URL и других чувствительных данных.

Исходный текст

django.mdc · CC0-1.0
---
description: Definitive guidelines for writing maintainable, performant, and secure Django applications, emphasizing modern best practices, clear code organization, and efficient patterns.
globs: **/*.py
---
# django Best Practices

This guide outlines the definitive best practices for developing Django applications, ensuring maintainability, performance, and security. Adhere to these rules for consistent, high-quality code.

## 1. Code Organization & Project Structure

Adopt the `src-layout` for clear separation of concerns. Keep apps focused on a single domain.

*   **Project Layout (`src-layout`)**:
    ```
    .
    ├── manage.py
    ├── src/
    │   ├── config/             # Project-level settings, URLs, WSGI/ASGI
    │   │   ├── __init__.py
    │   │   ├── settings/
    │   │   │   ├── __init__.py
    │   │   │   ├── base.py
    │   │   │   ├── development.py
    │   │   │   └── production.py
    │   │   └── urls.py
    │   ├── apps/               # Domain-driven Django apps
    │   │   ├── users/
    │   │   │   ├── models.py
    │   │   │   ├── views.py
    │   │   │   └── tests/
    │   │   ├── products/
    │   │   └── ...
    │   └── common/             # Reusable utilities, abstract base models, etc.
    └── requirements.txt
    ```

*   **Split Settings**: Use `django-environ` for environment-specific settings. Never commit secrets.

    ❌ BAD: Hardcoding secrets, single `settings.py`
    ```python
    # config/settings.py
    DEBUG = True
    SECRET_KEY = 'super-secret-dev-key'
    DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3'}}
    ```

    ✅ GOOD: Environment variables, split files
    ```python
    # src/config/settings/base.py
    import environ
    env = environ.Env()
    environ.Env.read_env() # reads .env file

    SECRET_KEY = env('SECRET_KEY')
    DEBUG = env.bool('DEBUG', default=False)
    ALLOWED_HOSTS = env.list('ALLOWED_HOSTS', default=[])

    # src/config/settings/development.py
    from .base import *
    DEBUG = True
    DATABASES = {'default': env.db('DATABASE_URL', default='sqlite:///db.sqlite3')}

    # .env file (not committed to VCS)
    SECRET_KEY=your_actual_secret_key
    DEBUG=True
    DATABASE_URL=postgres://user:pass@host:port/dbname
    ```

*   **Model Naming**: Models are singular nouns. `related_name` for reverse relationships is plural.

    ❌ BAD:
    ```python
    class Users(models.Model): pass
    owner = models.ForeignKey(Owner, related_name='item')
    ```

    ✅ GOOD:
    ```python
    class User(models.Model): pass
    owner = models.ForeignKey(Owner, related_name='items', on_delete=models.CASCADE)
    ```

## 2. Common Patterns & Anti-patterns

*   **Fat Models, Skinny Views**: Business logic belongs in models or dedicated service layers, not views. Views orchestrate, models/services execute.

    ❌ BAD: Logic in view
    ```python
    # apps/orders/views.py
    def create_order_view(request):
        # ... validation ...
        product = Product.objects.get(id=product_id)
        if product.stock < quantity:
            raise ValidationError("Not enough stock")
        order = Order.objects.create(user=request.user, product=product, quantity=quantity)
        product.stock -= quantity
        product.save()
        # ...
    ```

    ✅ GOOD: Logic in model/service
    ```python
    # apps/orders/models.py
    class Order(models.Model):
        # ... fields ...
        @classmethod
        def create_with_stock_check(cls, user, product, quantity):
            if product.stock < quantity:
                raise ValidationError("Not enough stock")
            order = cls.objects.create(user=user, product=product, quantity=quantity)
            product.stock -= quantity
            product.save()
            return order

    # apps/orders/views.py
    def create_order_view(request):
        # ... validation ...
        order = Order.create_with_stock_check(request.user, product, quantity)
        # ...
    ```

## 3. Performance Considerations

*   **Optimize ORM Queries**: Avoid N+1 queries.

    ❌ BAD: N+1 query
    ```python
    # Iterates over users, then queries profile for each
    users = User.objects.all()
    for user in users:
        print(user.profile.bio)
    ```

    ✅ GOOD: `select_related` (one-to-one, foreign key)
    ```python
    users = User.objects.select_related('profile').all()
    for user in users:
        print(user.profile.bio)
    ```

    ✅ GOOD: `prefetch_related` (many-to-many, reverse foreign key)
    ```python
    # For a list of books, prefetch all authors for each book
    books = Book.objects.prefetch_related('authors').all()
    for book in books:
        print([author.name for author in book.authors.all()])
    ```

*   **Database Indexes**: Add `db_index=True` to frequently filtered/ordered fields.
    ```python
    class MyModel(models.Model):
        name = models.CharField(max_length=100, db_index=True) # Indexed
        created_at = models.DateTimeField(auto_now_add=True, db_index=True)
    ```

*   **Async ORM**: Use `sync_to_async` for blocking ORM calls in async views, or the native async ORM (Django 4.1+).

    ```python
    # In an async view
    from asgiref.sync import sync_to_async

    async def my_async_view(request):
        # Blocking ORM call, wrap it
        user = await sync_to_async(User.objects.get)(id=request.user.id)
        # Or, if using native async ORM (Django 4.1+):
        # user = await User.objects.aget(id=request.user.id)
        return JsonResponse({'username': user.username})
    ```

## 4. Security Best Practices

*   **Secrets Management**: Never commit secrets to VCS. Use environment variables (see Split Settings).

*   **Permissions (DRF)**: Implement role-based permissions using DRF's `permission_classes`.

    ❌ BAD: Manual checks in view
    ```python
    class MyView(APIView):
        def get(self, request):
            if not request.user.is_staff:
                return Response(status=403)
            # ...
    ```

    ✅ GOOD: DRF Permission Classes
    ```python
    from rest_framework.permissions import IsAdminUser

    class MyView(APIView):
        permission_classes = [IsAdminUser] # Only staff can access
        def get(self, request):
            # ...
    ```

*   **Static & Media Files**: Serve static files with `ManifestStaticFilesStorage` and media files from cloud storage (e.g., S3, GCS).

    ```python
    # config/settings/production.py
    STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
    DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' # e.g., django-storages
    ```

## 5. API Design (DRF)

*   **ViewSets & Routers**: Use `ModelViewSet` for CRUD operations to reduce boilerplate.

    ❌ BAD: Separate views for list and detail
    ```python
    class ProductListView(APIView): pass
    class ProductDetailView(APIView): pass
    # urls.py: path('products/', ProductListView.as_view()), path('products/<int:pk>/', ProductDetailView.as_view())
    ```

    ✅ GOOD: `ModelViewSet` with Router
    ```python
    # apps/products/views.py
    from rest_framework import viewsets
    from .models import Product
    from .serializers import ProductSerializer

    class ProductViewSet(viewsets.ModelViewSet):
        queryset = Product.objects.all()
        serializer_class = ProductSerializer

    # src/config/urls.py
    from rest_framework.routers import DefaultRouter
    from apps.products.views import ProductViewSet

    router = DefaultRouter()
    router.register(r'products', ProductViewSet)
    urlpatterns = [
        # ...
        path('api/', include(router.urls)),
    ]
    ```

## 6. Type Hints

Always use type hints for improved readability, maintainability, and static analysis with `mypy`.

❌ BAD: Untyped function
```python
def calculate_total(price, quantity):
    return price * quantity
```

✅ GOOD: Typed function
```python
def calculate_total(price: float, quantity: int) -> float:
    return price * quantity

# For models:
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from django.db.models import QuerySet

class Product(models.Model):
    name: str = models.CharField(max_length=255)
    price: float = models.DecimalField(max_digits=10, decimal_places=2)

    def get_related_products(self) -> "QuerySet[Product]":
        # ...
        return Product.objects.filter(...)
```

© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc

Похожие правила IDE

Все правила IDE по теме «Бэкенд и API» →
django-expert https://github.com/Jeffallan Скилл помогает проектировать модели Django 5.0, настраивать сериализаторы DRF, оптимизировать ORM-запросы и конфигурировать аутентификацию по JWT. CX Codex +1 4 200установок ac-django souliane Свод правил по Django 6.1 и 5.2 LTS с акцентом на концепцию Fat Models, миграции и безопасность. Помогает писать модели, тесты и код для DRF. CX Codex +1 555установок django-access-review getsentry Скилл ищет IDOR и дыры в авторизации Django: проходит по вьюхам, DRF-вьюсетам и ORM-запросам и показывает, где проверок не хватает. CX Codex +1 2 700установок django-patterns affaan-m Помогает проектировать архитектуру Django и DRF: настраивать раздельные конфигурации, писать кастомные QuerySet и организовывать структуру приложений. CX Codex +1 5 200установок django-developer VoltAgent Community Субагент для разработки бэкенда на Django 4+ и Python 3.11+. Помогает проектировать модели ORM, настраивать Django REST Framework и писать тесты. 344установок django-rest-api-development Mindrally Скилл задаёт агенту правила разработки REST API на Django: структура проекта, сериализаторы, JWT-аутентификация и работа с запросами к базе. CX Codex +1 868установок

Из того же набора240

Весь набор →
elasticsearch Инструкция по работе с Elasticsearch в Cursor: учит модель настраивать маппинги, фильтровать запросы через filter и дробить шарды. ★ 3 580звёзд репо duckdb Правило задаёт стиль и практики для DuckDB SQL: от CTE и настроек сессии до загрузки данных и индексов. Пригодится при написании и рефакторинге аналитических запросов. ★ 3 580звёзд репо drizzle Правило задаёт агенту Cursor стиль работы с Drizzle ORM: модульные схемы, явные ограничения полей и единый нейминг в TypeScript-проекте. ★ 3 580звёзд репо docker Правило настраивает Cursor для создания Dockerfile и docker-compose файлов с многоэтапной сборкой и запуском без root-прав. ★ 3 580звёзд репо django-rest-framework Правило Cursor, которое задаёт агенту единый стиль разработки API на Django REST Framework: структура проекта, сериализаторы, ViewSets. ★ 3 580звёзд репо django-orm Набор инструкций для Cursor по работе с Django ORM. Помогает структурировать модели и убирать проблему N+1 в запросах к базе. ★ 3 580звёзд репо discord-api Правило помогает писать Discord-приложения с REST-запросами, типами API и обработкой интеракций. Пригодится при разработке бота на TypeScript. ★ 3 580звёзд репо digitalocean Правило для Cursor задаёт, как строить и разворачивать приложения в DigitalOcean: VPC, managed-сервисы, контейнеры. ★ 3 580звёзд репо

Спонсоры проекта

Компании, которые помогают держать аналитику открытой