AI结对编程实战:基于Cursor与Django的高效全栈开发指南
1. 项目概述当AI代码助手遇上Django全栈开发如果你是一名独立开发者、小团队的技术负责人或者正在尝试用AI工具提升开发效率的创业者那么“Cursor-Django”这个项目绝对值得你花时间研究。这不是一个简单的Django项目模板而是一套由资深开发者社区“Coding for Entrepreneurs”精心打磨的、专门为配合Cursor这类AI代码助手进行高效全栈开发而设计的实战指南与脚手架。它的核心价值在于它不仅仅告诉你“Django可以做什么”而是手把手教你“如何在与AI结对编程Pair Programming的新范式下最高效地构建一个现代化的、可维护的、功能完整的Web应用”。我最初接触这个项目是因为在尝试用Cursor重构一个旧有的Django后台时发现AI助手虽然能生成代码片段但在项目结构、配置约定、前后端协作等“大局观”上常常给出不一致甚至冲突的建议。我需要一个“标准答案”一个被验证过的最佳实践集合来引导AI助手和我自己确保我们始终在正确的轨道上协作。“Cursor-Django”恰好提供了这个答案。它基于一个真实的SaaS应用场景一个用户订阅管理系统覆盖了从环境搭建、模型设计、API构建、前端交互到部署上线的全流程并且每一处设计都考虑了如何用自然语言清晰地给AI下指令。简单来说它把Django开发中那些“只可意会不可言传”的经验变成了可以被AI理解和执行的明确规则。这个项目适合所有希望将AI深度融入开发工作流的Django开发者。无论你是想快速验证一个创业点子还是希望提升现有团队的开发速度与代码质量这套方法论和配套的代码结构都能提供极大的助力。它降低了全栈开发的心智负担让你能更专注于业务逻辑和创新而不是在无尽的配置和踩坑中消耗精力。2. 核心设计哲学为AI协作而生的项目结构2.1 为什么传统Django项目结构不适合AI助手在深入代码之前我们必须先理解这个项目要解决的根本问题。传统的Django项目结构比如通过django-admin startproject生成的是清晰且模块化的但它预设的是一种“人类开发者独自阅读文档和源码”的工作模式。当AI助手介入时这种结构会暴露出几个痛点上下文碎片化AI助手如Cursor通常基于当前打开的文件和有限的上下文窗口来提供建议。在传统的apps/目录下模型models.py、视图views.py、序列化器serializers.py、URL配置urls.py是分离的。当你让AI“为用户模型添加一个订阅状态字段并创建对应的API端点”时它需要在你给出的指令中同时理解并修改多个分散的文件极易出错或产生不一致。配置约定不明确Django的强大也带来了灵活性而灵活性在没有明确约定的团队或人机协作中就是灾难。例如静态文件处理、环境变量管理、第三方包集成如DRF、Celery每个项目可能都有不同的做法。AI助手无法猜测你个人的偏好导致生成的代码可能需要大量手动调整才能融入你的项目。缺乏端到端的用例引导新手包括AI看官方教程学的是一个个孤立的功能点如何创建模型、如何写视图。但真实项目开发是功能点的串联。缺少一个从零到一、贯穿前后端的完整示例AI很难理解各个模块如何协同工作来满足一个具体的用户故事User Story。“Cursor-Django”项目的设计哲学正是为了系统性地解决这些问题。它的目标不是取代Django而是为Django披上一层“AI友好”的外衣建立一套强约定的、上下文集中的、用例驱动的开发规范。2.2 模块化与上下文集中src/目录的奥秘项目最显著的特征是采用了src/源代码目录布局这是一种在现代Python项目中日益流行的结构。它将所有应用代码和项目配置集中于一个顶层目录下与依赖管理文件requirements.txt、文档、部署脚本等清晰分离。cursor-django-project/ ├── .cursorrules # AI助手行为规则文件核心 ├── .env.example ├── .gitignore ├── README.md ├── requirements/ │ ├── base.txt │ ├── local.txt │ └── production.txt └── src/ # 所有核心代码在此 ├── config/ # Django项目设置原project目录 │ ├── __init__.py │ ├── asgi.py │ ├── settings/ # 拆分的环境配置 │ ├── urls.py │ └── wsgi.py ├── apps/ # 自定义Django应用 │ └── subscriptions/ # 示例订阅应用 │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations/ │ ├── models.py │ ├── serializers.py # API序列化器 │ ├── tests.py │ ├── urls.py # 应用级URL │ └── views.py # API视图集 ├── static/ ├── templates/ └── manage.py这种结构的优势在于“上下文集中”。当你打开src/apps/subscriptions/目录时与“订阅”功能相关的所有代码模型、视图、序列化器、URL、测试都近在咫尺。你可以轻松地告诉Cursor“打开订阅应用的模型文件并参考同目录下的视图和序列化器为Plan模型添加一个is_active布尔字段并确保API能正确过滤。” AI助手能在一个较小的、高相关性的上下文窗口内理解并执行这个复杂的指令因为它能看到所有相关的组件。实操心得我强烈建议在项目初期就严格遵循这种“功能模块内聚”的目录结构。即使是一个很小的功能也为其创建一个独立的Django应用python manage.py startapp your_feature并放入src/apps/。这为未来的功能扩展和AI协作打下了极好的基础。不要因为“暂时简单”就把所有代码堆在同一个应用里。2.3.cursorrules定义人机协作的“宪法”这是本项目最具创新性的部分。.cursorrules是一个纯文本文件用于定义Cursor AI助手在整个项目中的行为准则和偏好。你可以把它理解为项目的“开发宪法”或“AI提示词工程的核心配置”。它不属于Django但深刻影响着Django的开发方式。一个典型的.cursorrules文件会包含以下内容# .cursorrules [Project Context] 本项目是一个基于Django和Django REST Framework (DRF)构建的现代SaaS Web应用后端。采用src布局所有Django应用位于src/apps/目录下。前端计划使用React/Vue通过DRF API交互。 [Code Style] - 使用PEP 8 Python代码风格。 - Django模型字段名使用蛇形命名法snake_case如user_profile。 - DRF序列化器Serializer和视图集ViewSet命名遵循ModelNameSerializer ModelNameViewSet。 - 所有API视图必须基于viewsets.ModelViewSet或generics.*避免使用基于函数的视图FBV以保持一致性。 - 为所有模型编写全面的__str__方法。 - 在settings/base.py中定义项目级常量而非硬编码。 [AI Interaction Guidelines] - 当被要求创建新的Django应用时请生成完整的应用结构models, admin, serializers, views, urls, tests。 - 在编写视图时请同时考虑并提示是否需要更新对应的serializers.py和urls.py。 - 生成模型字段时请包含常用的参数如verbose_name, null, blank, default并简要说明原因。 - 优先使用DRF的内置权限类如IsAuthenticated, IsAdminUser和过滤器DjangoFilterBackend。这个文件的作用是主动塑造AI的思维模式。它提前回答了AI在生成代码时可能遇到的大部分“选择性问题”将你的项目偏好固化为规则。这样一来你就不需要在每次发出指令时都重复说“请使用DRF的ModelViewSet”、“请记得添加verbose_name”。AI会默认遵守这些规则生成出高度符合项目规范的代码极大减少了后期调整的工作量。注意事项.cursorrules文件需要随着项目技术栈的演进而更新。例如如果你决定引入Celery处理异步任务或者切换数据库都应该及时更新这个文件。把它当作重要的项目文档来维护。3. 环境配置与开发工作流搭建3.1 基于requirements/目录的依赖管理清晰、可重现的依赖管理是团队协作和AI理解项目环境的基石。“Cursor-Django”项目没有使用单一的requirements.txt而是采用了分层的依赖管理结构requirements/ ├── base.txt # 所有环境共享的核心依赖Django, DRF, psycopg2等 ├── local.txt # 本地开发环境额外依赖调试工具、测试库 └── production.txt # 生产环境额外依赖性能优化、监控base.txt列出了项目运行不可或缺的包如Django,djangorestframework,psycopg2-binary(PostgreSQL驱动)python-dotenv(环境变量管理)。local.txt则通过-r base.txt引入基础依赖并添加ipdb,django-debug-toolbar,pytest等仅用于开发和测试的工具。production.txt同理可能会包含gunicorn,whitenoise,sentry-sdk等。这种做法的好处是环境隔离与意图清晰。当你告诉AI助手“请为项目添加一个用于性能分析的依赖”它可以很明确地将django-silk添加到local.txt中而不是base.txt。这避免了将生产环境不需要的调试工具部署上线也使得不同环境下的依赖列表一目了然。安装依赖的实操命令# 进入项目根目录 cd cursor-django-project # 创建虚拟环境推荐使用venv python -m venv venv # 激活虚拟环境 # Windows: venv\Scripts\activate # macOS/Linux: source venv/bin/activate # 安装本地开发环境依赖 pip install -r requirements/local.txt3.2 环境变量与多环境设置管理将敏感信息如SECRET_KEY、数据库密码和与环境相关的配置如DEBUG模式、API密钥硬编码在settings.py中是极不安全且不灵活的做法。本项目采用了python-dotenv加拆分settings模块的最佳实践。在src/config/settings/目录下你会看到base.py: 存放所有环境通用的设置。local.py: 继承自base.py覆盖本地开发特定设置如DEBUGTrue。production.py: 继承自base.py覆盖生产环境特定设置如DEBUGFalse, 配置静态文件存储、日志等。项目的src/config/settings/__init__.py文件通常会根据一个环境变量如DJANGO_SETTINGS_MODULE或自定义的ENVIRONMENT来动态决定加载哪个环境的配置。更常见的做法是在base.py开头使用python-dotenv从.env文件加载变量。一个典型的.env文件示例# .env DEBUGTrue SECRET_KEYyour-secret-key-here-for-development-only DATABASE_URLpostgres://user:passwordlocalhost:5432/cursor_dev ALLOWED_HOSTSlocalhost,127.0.0.1在base.py中加载# src/config/settings/base.py from pathlib import Path from dotenv import load_dotenv import os # 构建路径到项目根目录的 .env 文件 BASE_DIR Path(__file__).resolve().parent.parent.parent.parent load_dotenv(BASE_DIR / .env) SECRET_KEY os.getenv(SECRET_KEY) DEBUG os.getenv(DEBUG) True # ... 其他从环境变量读取的配置重要提示务必在.gitignore中添加.env确保密码等敏感信息不会提交到版本库。团队中应共享一个.env.example文件列出所有需要的环境变量键名及其示例值。3.3 初始化数据库与运行项目配置好环境和变量后初始化Django项目就变得非常标准化这正好是AI助手擅长执行的重复性任务。你可以直接给Cursor如下指令“请按照当前项目结构执行Django数据库迁移并创建超级用户。” AI助手可以生成或直接执行以下命令序列# 确保在src目录下 cd src # 应用数据库迁移 python manage.py migrate # 创建超级用户交互式AI会提示你输入用户名、邮箱、密码 python manage.py createsuperuser # 运行本地开发服务器 python manage.py runserver此时访问http://127.0.0.1:8000/admin/并使用刚创建的超级用户登录你应该能看到Django管理后台。如果项目包含了示例应用如subscriptions你还需要为其生成迁移文件并应用python manage.py makemigrations subscriptions python manage.py migrate这套清晰、分层的配置和工作流使得项目的搭建过程对AI和新人开发者都极其友好。任何指令都可以基于明确的位置src/目录和明确的规则.cursorrules和分层配置来执行大大降低了沟通和执行的歧义。4. 核心应用开发以订阅系统为例的AI协作实战“Cursor-Django”项目通过一个具体的“用户订阅管理系统”示例来演示如何在实际功能开发中与AI高效协作。我们以此为例拆解几个关键场景。4.1 使用AI快速构建数据模型Models假设我们需要为订阅系统创建核心模型Plan套餐、Subscription用户订阅记录。传统的做法是打开models.py手动编写。而现在你可以向Cursor提出一个综合性的需求你的指令“在src/apps/subscriptions/应用下创建Plan和Subscription模型。Plan需要包含名称、描述、价格、周期月/年、是否活跃字段。Subscription需要关联Django内置的User模型和Plan模型包含开始时间、结束时间、状态active, canceled, expired和Stripe的客户ID与订阅ID。请使用合理的字段类型和参数并添加__str__方法。”基于.cursorrules的约定和Django的知识一个合格的AI助手会生成类似下面的代码并且它可能会在注释中解释关键字段的选择理由# src/apps/subscriptions/models.py from django.db import models from django.conf import settings class Plan(models.Model): 订阅套餐计划 # 使用CharField存储短文本max_length需明确 name models.CharField(max_length100, verbose_name套餐名称) description models.TextField(verbose_name套餐描述, blankTrue) # 使用DecimalField存储金额避免浮点数精度问题 price models.DecimalField( max_digits10, decimal_places2, verbose_name价格 ) # 使用choices参数限制可选值提高数据一致性和Admin界面友好度 BILLING_CYCLE_MONTHLY monthly BILLING_CYCLE_YEARLY yearly BILLING_CYCLE_CHOICES [ (BILLING_CYCLE_MONTHLY, 按月), (BILLING_CYCLE_YEARLY, 按年), ] billing_cycle models.CharField( max_length20, choicesBILLING_CYCLE_CHOICES, defaultBILLING_CYCLE_MONTHLY, verbose_name计费周期 ) is_active models.BooleanField(defaultTrue, verbose_name是否激活) def __str__(self): return f{self.name} (${self.price}/{self.get_billing_cycle_display()}) class Meta: verbose_name 订阅套餐 verbose_name_plural verbose_name class Subscription(models.Model): 用户订阅记录 # 外键关联使用settings.AUTH_USER_MODEL保持用户模型可替换性 user models.ForeignKey( settings.AUTH_USER_MODEL, on_deletemodels.CASCADE, related_namesubscriptions, verbose_name用户 ) plan models.ForeignKey( Plan, on_deletemodels.PROTECT, # 防止误删套餐导致订阅记录无关联 related_namesubscriptions, verbose_name订阅套餐 ) start_date models.DateTimeField(verbose_name开始时间) end_date models.DateTimeField(verbose_name结束时间) STATUS_ACTIVE active STATUS_CANCELED canceled STATUS_EXPIRED expired STATUS_CHOICES [ (STATUS_ACTIVE, 活跃), (STATUS_CANCELED, 已取消), (STATUS_EXPIRED, 已过期), ] status models.CharField( max_length20, choicesSTATUS_CHOICES, defaultSTATUS_ACTIVE, verbose_name状态 ) # 用于与支付网关如Stripe关联的ID允许为空因为创建时可能尚未获得 stripe_customer_id models.CharField(max_length100, blankTrue, verbose_nameStripe客户ID) stripe_subscription_id models.CharField(max_length100, blankTrue, verbose_nameStripe订阅ID) def __str__(self): return f{self.user.email} - {self.plan.name} ({self.status}) class Meta: verbose_name 用户订阅 verbose_name_plural verbose_name # 确保一个用户对一个套餐只有一个活跃订阅简化逻辑实际可能更复杂 constraints [ models.UniqueConstraint( fields[user, plan], conditionmodels.Q(statusSTATUS_ACTIVE), nameunique_active_subscription_per_user_plan ) ]实操心得在让AI生成模型时一定要在指令中明确“关联关系”ForeignKey, ManyToMany和“业务约束”如唯一性约束UniqueConstraint。AI能生成正确的字段但复杂的业务规则需要你主动提出。生成后务必检查on_delete参数是否符合你的业务逻辑如CASCADE级联删除还是PROTECT保护。4.2 驱动AI创建序列化器Serializers与视图集ViewSets模型创建好后下一步是暴露API。根据.cursorrules的约定我们应该使用DRF的ModelViewSet和ModelSerializer。指令可以非常直接你的指令“请为刚才创建的Plan和Subscription模型创建对应的DRF ModelSerializer和ModelViewSet并注册到应用的urls.py中。Subscription的序列化器要嵌套显示Plan的详细信息。API需要基本的认证和权限控制。”AI助手会依次生成或更新以下文件1. 序列化器 (serializers.py):# src/apps/subscriptions/serializers.py from rest_framework import serializers from .models import Plan, Subscription class PlanSerializer(serializers.ModelSerializer): class Meta: model Plan fields __all__ # 在实际项目中可能只暴露部分字段如id, name, price, billing_cycle class SubscriptionSerializer(serializers.ModelSerializer): # 嵌套序列化在API响应中直接包含完整的Plan对象信息减少前端请求次数 plan PlanSerializer(read_onlyTrue) # 用户字段通常只读或由后端自动关联不从前端接收 user serializers.HiddenField(defaultserializers.CurrentUserDefault()) class Meta: model Subscription fields [id, user, plan, start_date, end_date, status, stripe_customer_id, stripe_subscription_id] read_only_fields [start_date, end_date, status] # 这些字段可能由业务逻辑自动设置2. 视图集 (views.py):# src/apps/subscriptions/views.py from rest_framework import viewsets, permissions from .models import Plan, Subscription from .serializers import PlanSerializer, SubscriptionSerializer class PlanViewSet(viewsets.ModelViewSet): API端点允许查看和编辑套餐计划。 queryset Plan.objects.filter(is_activeTrue) # 默认只返回活跃套餐 serializer_class PlanSerializer # 通常套餐信息对所有认证用户可读但只有管理员可修改 permission_classes [permissions.IsAuthenticatedOrReadOnly] class SubscriptionViewSet(viewsets.ModelViewSet): API端点管理用户订阅。 用户只能查看和操作自己的订阅。 serializer_class SubscriptionSerializer permission_classes [permissions.IsAuthenticated] # 必须登录 def get_queryset(self): # 重写此方法确保用户只能访问自己的订阅记录 return Subscription.objects.filter(userself.request.user) def perform_create(self, serializer): # 在创建订阅时自动将当前用户关联到订阅记录 serializer.save(userself.request.user)3. URL配置 (urls.py):# src/apps/subscriptions/urls.py from django.urls import path, include from rest_framework.routers import DefaultRouter from . import views router DefaultRouter() router.register(rplans, views.PlanViewSet) router.register(rsubscriptions, views.SubscriptionViewSet, basenamesubscription) urlpatterns [ path(, include(router.urls)), ]4. 将应用URL包含到项目主URL中 AI还会提示你需要更新src/config/urls.py# src/config/urls.py from django.contrib import admin from django.urls import path, include urlpatterns [ path(admin/, admin.site.urls), path(api/subscriptions/, include(src.apps.subscriptions.urls)), # 添加这行 # ... 其他API路径 ]这一套指令下来一个具备完整CRUD操作、权限控制、数据关联的RESTful API就搭建完毕了。AI不仅生成了代码还遵循了最佳实践如使用DefaultRouter自动生成URL、在视图集中覆写get_queryset实现数据隔离、使用HiddenField和CurrentUserDefault自动处理用户关联。4.3 利用AI生成管理后台Admin配置Django Admin是快速构建管理后台的神器。我们可以让AI为模型生成功能更强大的Admin配置。你的指令“为Plan和Subscription模型创建Django Admin配置。要求在Admin列表页显示更多字段为Subscription添加过滤器按状态、按用户为Plan添加搜索功能并注册模型。”AI生成的admin.py可能如下# src/apps/subscriptions/admin.py from django.contrib import admin from .models import Plan, Subscription class PlanAdmin(admin.ModelAdmin): list_display (name, price, billing_cycle, is_active) # 列表页显示字段 list_filter (is_active, billing_cycle) # 右侧过滤器 search_fields (name, description) # 搜索框 list_editable (is_active,) # 可直接在列表页编辑是否激活 ordering (price,) # 默认按价格排序 class SubscriptionAdmin(admin.ModelAdmin): list_display (user, plan, status, start_date, end_date) list_filter (status, plan, start_date) # 强大的过滤侧边栏 raw_id_fields (user,) # 对于大量用户的ForeignKey使用raw_id字段提升性能 search_fields (user__email, stripe_subscription_id) # 支持关联字段搜索 date_hierarchy start_date # 按日期层级钻取 admin.site.register(Plan, PlanAdmin) admin.site.register(Subscription, SubscriptionAdmin)通过这样具体的指令AI能够生成远超Django默认Admin界面的、高度定制化的管理面板极大提升了运营人员的管理效率。5. 前后端分离实践与API调试5.1 配置DRF与API文档在现代化的全栈开发中清晰、可交互的API文档至关重要。项目通常会集成DRF自带的API Web界面和第三方文档工具如drf-yasg或drf-spectacular。你可以指示AI“请为项目配置Django REST Framework并集成drf-spectacular以生成OpenAPI文档。同时在本地开发环境中启用DRF的可浏览API界面。”AI会更新settings/base.py或local.py并添加必要的URL配置# 在 settings/base.py 或 local.py 中添加 INSTALLED_APPS [ # ... rest_framework, drf_spectacular, # API文档生成 # ... ] REST_FRAMEWORK { DEFAULT_SCHEMA_CLASS: drf_spectacular.openapi.AutoSchema, DEFAULT_AUTHENTICATION_CLASSES: [ rest_framework.authentication.SessionAuthentication, # 用于可浏览API rest_framework.authentication.TokenAuthentication, # 或JWT用于前端 ], DEFAULT_PERMISSION_CLASSES: [ rest_framework.permissions.IsAuthenticated, # 默认需要认证各视图可覆盖 ], DEFAULT_PAGINATION_CLASS: rest_framework.pagination.PageNumberPagination, PAGE_SIZE: 20 } # drf-spectacular 配置 SPECTACULAR_SETTINGS { TITLE: 订阅管理系统 API, DESCRIPTION: 一个演示用的用户订阅管理后端API, VERSION: 1.0.0, }# 在 src/config/urls.py 中添加 from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView urlpatterns [ # ... path(api/schema/, SpectacularAPIView.as_view(), nameschema), path(api/docs/, SpectacularSwaggerView.as_view(url_nameschema), nameswagger-ui), # ... ]现在访问http://127.0.0.1:8000/api/docs/就能看到一个漂亮的Swagger UI界面可以查看所有API端点并进行交互式测试。这不仅是给前端开发者的礼物也是你调试和验证API的利器。5.2 使用AI辅助进行API测试编写测试是保证代码质量的关键但也是最容易被忽视的环节。AI可以极大地简化测试代码的编写。例如你可以要求“为SubscriptionViewSet的create和list动作编写DRF APITestCase测试。测试用户只能创建和查看自己的订阅。”AI可能会生成如下测试# src/apps/subscriptions/tests.py from django.contrib.auth import get_user_model from rest_framework.test import APITestCase, APIClient from rest_framework import status from .models import Plan, Subscription User get_user_model() class SubscriptionAPITests(APITestCase): def setUp(self): # 创建测试数据 self.user1 User.objects.create_user(emailuser1test.com, passwordpass123) self.user2 User.objects.create_user(emailuser2test.com, passwordpass123) self.plan Plan.objects.create(name基础版, price10, billing_cyclemonthly) self.client APIClient() def test_authenticated_user_can_create_subscription(self): 认证用户可以创建自己的订阅 self.client.force_authenticate(userself.user1) url /api/subscriptions/subscriptions/ data {plan: self.plan.id} response self.client.post(url, data, formatjson) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Subscription.objects.count(), 1) self.assertEqual(Subscription.objects.first().user, self.user1) def test_user_can_only_see_own_subscriptions(self): 用户只能看到自己的订阅列表 # 为用户1和用户2各创建一个订阅 Subscription.objects.create(userself.user1, planself.plan) Subscription.objects.create(userself.user2, planself.plan) # 用户1登录 self.client.force_authenticate(userself.user1) response self.client.get(/api/subscriptions/subscriptions/) self.assertEqual(response.status_code, status.HTTP_200_OK) # 确保返回的数据只有一条且属于user1 self.assertEqual(len(response.data[results]), 1) # 注意分页结构 self.assertEqual(response.data[results][0][user], self.user1.id) def test_unauthenticated_user_cannot_access_subscriptions(self): 未认证用户无法访问订阅API url /api/subscriptions/subscriptions/ response self.client.get(url) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)运行测试只需一个命令python manage.py test src.apps.subscriptions。通过让AI编写这些样板化的测试代码你可以将更多精力放在设计复杂的业务逻辑测试上。6. 部署准备与生产环境考量6.1 静态文件与媒体文件处理Django的开发服务器能处理静态文件但生产环境需要更高效的方案。项目通常会使用whitenoise来服务静态文件并使用云存储如AWS S3、Google Cloud Storage或反向代理如Nginx来处理媒体文件。你可以指示AI“请配置项目以使用whitenoise在生产环境服务静态文件并假设媒体文件将使用AWS S3请提供相应的Django配置示例。”AI会更新production.py设置并可能给出安装建议# settings/production.py from .base import * DEBUG False ALLOWED_HOSTS os.getenv(ALLOWED_HOSTS, ).split(,) # Whitenoise 配置 MIDDLEWARE [ django.middleware.security.SecurityMiddleware, whitenoise.middleware.WhiteNoiseMiddleware, # 紧跟在SecurityMiddleware之后 # ... 其他中间件 ] # 静态文件配置 STATIC_URL /static/ STATIC_ROOT BASE_DIR / staticfiles STATICFILES_STORAGE whitenoise.storage.CompressedManifestStaticFilesStorage # 媒体文件配置 (AWS S3示例需要安装django-storages和boto3) # DEFAULT_FILE_STORAGE storages.backends.s3boto3.S3Boto3Storage # AWS_ACCESS_KEY_ID os.getenv(AWS_ACCESS_KEY_ID) # AWS_SECRET_ACCESS_KEY os.getenv(AWS_SECRET_ACCESS_KEY) # AWS_STORAGE_BUCKET_NAME os.getenv(AWS_STORAGE_BUCKET_NAME) # AWS_S3_REGION_NAME os.getenv(AWS_S3_REGION_NAME, us-east-1) # AWS_S3_CUSTOM_DOMAIN f{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com # MEDIA_URL fhttps://{AWS_S3_CUSTOM_DOMAIN}/media/同时AI会提示你更新生产环境依赖requirements/production.txt添加whitenoise和boto3、django-storages等包。6.2 数据库、缓存与异步任务配置生产环境还需要考虑数据库连接池、缓存如Redis和异步任务队列如Celery。虽然“Cursor-Django”示例项目可能未完全展开但你可以引导AI为你搭建基础框架。指令示例“请为生产环境配置PostgreSQL数据库连接使用dj-database-url解析DATABASE_URL并添加Redis作为缓存和后端为Celery做准备的配置示例。”AI生成的配置可能如下# settings/production.py import dj_database_url DATABASES { default: dj_database_url.config( conn_max_age600, # 连接池连接存活时间 conn_health_checksTrue, defaultos.getenv(DATABASE_URL) ) } # Redis缓存配置 CACHES { default: { BACKEND: django_redis.cache.RedisCache, LOCATION: os.getenv(REDIS_URL, redis://127.0.0.1:6379/1), OPTIONS: { CLIENT_CLASS: django_redis.client.DefaultClient, # 可添加更多选项如密码、socket超时等 } } } # Celery配置 (基础) CELERY_BROKER_URL os.getenv(REDIS_URL, redis://127.0.0.1:6379/0) CELERY_RESULT_BACKEND os.getenv(REDIS_URL, redis://127.0.0.1:6379/0)6.3 使用Docker进行容器化可选但推荐对于现代部署Docker几乎是标配。你可以让AI为你创建一个基础的Dockerfile和docker-compose.yml文件用于定义开发和生产环境。指令“请创建一个用于生产环境的Dockerfile基于Python官方镜像包含安装依赖、收集静态文件、运行Gunicorn的步骤。再创建一个docker-compose.yml定义PostgreSQL和Redis服务。”虽然生成完整的部署配置需要更多细节但AI可以提供一个极佳的起点# Dockerfile FROM python:3.11-slim # 设置工作目录 WORKDIR /app # 设置环境变量 ENV PYTHONDONTWRITEBYTECODE1 ENV PYTHONUNBUFFERED1 # 安装系统依赖 RUN apt-get update apt-get install -y \ gcc \ libpq-dev \ rm -rf /var/lib/apt/lists/* # 安装Python依赖 COPY requirements/production.txt . RUN pip install --no-cache-dir -r production.txt # 复制项目代码 COPY src/ ./src/ COPY manage.py . # 收集静态文件在构建时进行需要确保settings模块可访问 RUN python manage.py collectstatic --noinput # 运行应用 CMD [gunicorn, --bind, 0.0.0.0:8000, config.wsgi:application]# docker-compose.yml version: 3.8 services: db: image: postgres:15 volumes: - postgres_data:/var/lib/postgresql/data environment: - POSTGRES_DBcursor_prod - POSTGRES_USERuser - POSTGRES_PASSWORDpassword healthcheck: test: [CMD-SHELL, pg_isready -U user] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine volumes: - redis_data:/data web: build: . command: gunicorn --bind 0.0.0.0:8000 config.wsgi:application volumes: - ./src:/app/src # 开发时可挂载源码生产环境通常不挂载 - static_volume:/app/staticfiles ports: - 8000:8000 environment: - DATABASE_URLpostgres://user:passworddb:5432/cursor_prod - REDIS_URLredis://redis:6379/0 - DJANGO_SETTINGS_MODULEconfig.settings.production - SECRET_KEYyour-production-secret-key-here # 应从外部secret注入 depends_on: db: condition: service_healthy redis: condition: service_started volumes: postgres_data: redis_data: static_volume:这个docker-compose.yml定义了一个包含数据库、缓存和应用服务的完整开发/测试环境。通过一条命令docker-compose up --build就能启动所有服务极大地简化了环境一致性管理。7. 常见问题、调试技巧与进阶思考7.1 与AI协作时的常见问题与解决思路即使有.cursorrules和良好的项目结构与AI协作时仍会遇到一些典型问题。问题1AI生成的代码不符合项目特定约定。现象AI使用了函数视图FBV而项目约定使用视图集ViewSet。解决首先检查.cursorrules文件是否明确写入了这条约定。其次在指令中要更具体。不要只说“创建一个API”而要说“使用DRF的ModelViewSet为X模型创建标准的CRUD API端点并遵循我们项目中的视图集模式”。如果AI仍然出错可以打开它之前生成正确的视图集文件作为参考然后要求它“参照PlanViewSet的写法为Y模型创建视图集”。问题2AI不理解复杂的业务逻辑。现象你需要一个在创建订阅时根据套餐周期自动计算结束日期的逻辑。AI可能只生成基础的保存操作。解决将复杂逻辑拆解。先让AI生成基础的perform_create方法。然后给出下一步指令“在SubscriptionSerializer的create方法或SubscriptionViewSet的perform_create方法中添加逻辑根据关联的Plan的billing_cycle字段‘monthly’或‘yearly’自动计算end_date例如从start_date开始增加1个月或1年。start_date默认为当前时间。” 必要时可以提供伪代码或计算公式。问题3AI生成的代码有语法错误或导入缺失。现象代码中引用了未导入的模块或使用了错误的函数名。解决这是AI的常见局限。不要期待一次生成完美代码。将其视为一个高效的“初级程序员”。你的角色是“技术负责人”需要进行代码审查Code Review。运行python manage.py check或直接尝试运行服务器Django会给出详细的错误信息。然后你可以将错误信息反馈给AI“你生成的代码在views.py第X行有导入错误SomeClass未找到。请检查并修正。” AI通常能根据错误信息快速修正。7.2 Django项目调试技巧充分利用Django Debug Toolbar在local.py中启用这个工具它能在浏览器侧边栏显示SQL查询、请求耗时、模板渲染等信息是性能分析和问题定位的利器。使用IPDB进行交互式调试在怀疑有问题的代码行前插入import ipdb; ipdb.set_trace()运行到此处时程序会暂停进入一个交互式shell可以查看当前所有变量、执行代码逐行调试。解读Django的错误页面Django的开发服务器在DEBUGTrue时提供的错误页面信息极其丰富。重点关注“Traceback”部分它精确指出了错误发生的文件和行数。查看“Local vars”可以了解出错时各个变量的值。管理命令是瑞士军刀多使用python manage.py shell_plus需要django-extensions进行快速的数据检查和操作。使用python manage.py showmigrations查看迁移状态python manage.py sqlmigrate app_label migration_name查看迁移将执行的SQL语句。7.3 项目后续演进与扩展建议“Cursor-Django”项目提供了一个坚实的起点。随着业务增长你可以考虑以下方向并继续利用AI进行辅助开发用户认证与授权进阶从简单的TokenAuthentication切换到更现代的JWT使用djangorestframework-simplejwt实现无状态认证、刷新令牌等功能。可以指示AI“集成djangorestframework-simplejwt配置登录、刷新令牌的API端点并设置令牌过期时间。”实时功能集成Django Channels为应用添加WebSocket支持实现实时通知、聊天等功能。指令可以是“为项目添加Django Channels支持创建一个简单的WebSocket消费者用于向已认证用户广播系统通知。”任务队列引入Celery和Redis处理发送邮件、生成报表、调用第三方API等耗时任务。让AI帮你“配置Celery创建一个异步任务在用户注册成功后发送欢迎邮件。”API性能优化使用django-debug-toolbar分析慢查询然后引入select_related、prefetch_related优化数据库查询或者使用django-redis-cache进行视图缓存。指令“分析SubscriptionViewSet的列表API的N1查询问题使用select_related优化对user和plan的查询。”前端集成虽然本项目侧重后端但你可以很容易地创建一个前端项目如Vite React并通过DRF的API与之交互。AI甚至可以帮你生成使用Axios或Fetch API调用后端接口的前端示例代码。“Cursor-Django”项目的精髓在于它展示了一种范式将你的开发经验、项目规范沉淀为明确的规则.cursorrules和清晰的结构src/布局从而将AI助手从一个“有时靠谱的代码补全工具”转变为一个“理解你项目上下文和偏好的高效协作伙伴”。它要求你在前期投入更多思考来定义规则但换来的是整个项目生命周期内开发效率的质的提升。这不仅仅是关于Django更是关于如何适应并驾驭AI编程新时代的思维方式。