ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

零基础入门python31:Django商城第一步——创建项目并跑通第一个请求

零基础入门python31:Django商城第一步——创建项目并跑通第一个请求 零基础入门python31Django商城第一步——创建项目并跑通第一个请求一、上一篇课后练习讲解Python 基础阶段最后一个练习是把命令行任务管理器拆成多个模块。参考做法是把“读取输入、校验、业务处理、保存文件”分开再用python -m从项目根目录启动。Django 项目也遵循同样的思路配置、路由、业务应用各有职责。上一篇课后练习完整答案上一篇练习的要求已落实到下面完整文件先运行项目测试再用 curl 对照状态码和数据库持久化结果答案要点README 验收从空目录创建虚拟环境、迁移、测试和冒烟记录版本、状态码和只读数据库等故障结果。文件README.md完整参考答案文件完整文件README.md# Flask Ledger 验收 python -m pip install -r requirements.txt flask --app run.py db upgrade python -m pytest -q flask --app run.py run完整参考答案文件本篇对应的交付源码完整文件flask-ledger/tests/test_app.pydeftest_health(client):assertclient.get(/api/health).get_json(){status:ok}deftest_register_login_and_me(client):responseclient.post(/api/auth/register,json{email:Aexample.com,password:password123})assertresponse.status_code201assertclient.post(/api/auth/login,json{email:aexample.com,password:password123}).status_code200assertclient.get(/api/auth/me).get_json()[email]aexample.comdeftest_ledger_flow(logged_client):categorylogged_client.post(/api/categories,json{name:餐饮}).get_json()createdlogged_client.post(/api/transactions,json{kind:expense,amount:28.50,category_id:category[id],happened_on:2026-08-06,note:午饭,})assertcreated.status_code201assertcreated.get_json()[amount]28.50itemslogged_client.get(/api/transactions).get_json()[items]assertlen(items)1statslogged_client.get(/api/statistics/monthly?month2026-08).get_json()assertstats[expense]28.50assertlogged_client.delete(f/api/transactions/{items[0][id]}).status_code204deftest_users_cannot_share_categories(client):client.post(/api/auth/register,json{email:firstexample.com,password:password123})client.post(/api/auth/login,json{email:firstexample.com,password:password123})categoryclient.post(/api/categories,json{name:工资}).get_json()client.post(/api/auth/logout)client.post(/api/auth/register,json{email:secondexample.com,password:password123})client.post(/api/auth/login,json{email:secondexample.com,password:password123})responseclient.post(/api/transactions,json{kind:income,amount:100,category_id:category[id]})assertresponse.status_code404验收命令python -m pytest -qDjango 项目使用 python manage.py test。预期测试通过若失败先检查迁移、配置和事务回滚。二、本篇完成什么今天不急着写商品和订单。我们先完成一件能验证环境的事情创建商城项目启动开发服务器访问/api/health/看到明确的 JSON 响应。如果这一步没有跑通后面所有模型、迁移和接口都会建立在错误环境上。三、Django项目到底是什么Django 项目由“配置容器”和“业务应用”组成config不应该保存商品业务shop不应该偷偷读取命令行参数。这样拆开后部署配置变化时不需要修改订单代码。四、创建项目在课程工作目录执行python-m venv.venv.venv\\Scripts\\activate pip installDjango5.0,6djangorestframework django-admin startproject config django-shop cd django-shop python manage.py startapp shop如果django-admin找不到说明虚拟环境没有激活如果ModuleNotFoundError: django说明依赖安装到了另一个 Python。五、配置应用1.config/settings.pyINSTALLED_APPS[# Django 自带用户、Session 和 Admin商城会直接复用它们。django.contrib.admin,django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,django.contrib.messages,django.contrib.staticfiles,rest_framework,shop,]REST_FRAMEWORK{# 未登录用户可以浏览商品需要购买时再在具体视图上收紧权限。DEFAULT_PERMISSION_CLASSES:[rest_framework.permissions.AllowAny],}INSTALLED_APPS决定 Django 是否加载模型、迁移和 Admin。把shop写进去后Django 才知道这个应用有数据库模型。2.shop/views.pyfromrest_framework.responseimportResponsefromrest_framework.viewsimportAPIViewclassHealthView(APIView):给容器编排和人工检查使用的轻量健康检查。authentication_classes[]permission_classes[]defget(self,request):# 健康检查不查询业务表避免数据库故障时把真实原因隐藏掉。returnResponse({status:ok,service:django-shop})这里没有把数据库查询放进健康检查因为第一篇只验证 Web 进程是否能响应。后面会增加/api/ready/专门检查数据库是否可用区分 liveness 和 readiness 是部署时很重要的设计。3.shop/urls.pyfromdjango.urlsimportpathfrom.viewsimportHealthView urlpatterns[path(health/,HealthView.as_view(),namehealth),]4.config/urls.pyfromdjango.contribimportadminfromdjango.urlsimportinclude,path urlpatterns[path(admin/,admin.site.urls),# 总路由只负责把 /api/ 交给 shop不实现业务细节。path(api/,include(shop.urls)),]六、启动和查看结果python manage.py check python manage.py migrate python manage.py runserver 127.0.0.1:8000另开一个终端curl http://127.0.0.1:8000/api/health/预期响应{status:ok,service:django-shop}check只检查配置migrate创建 Django 自带的用户和 Session 表runserver启动开发服务器。三条命令作用不同不要把runserver当成迁移命令。七、常见错误排查现象原因处理No module named django没有使用虚拟环境里的 Python重新激活.venv并运行python -m pip install404 /api/health总路由没有 includeshop.urls检查config/urls.py的path(api/, ...)Apps arent loaded yet在 Django 启动前导入模型把模型导入放进视图或正确的 Django 入口浏览器能访问、curl 失败端口或地址不一致确认 runserver 输出的监听地址八、本篇验收python manage.py check python manage.py test curl http://127.0.0.1:8000/api/health/验收标准system check 无问题测试通过健康检查返回 200 和 JSON删除健康检查视图中的注释不会影响行为但删除路由会导致 404。九、课后练习增加/api/version/接口返回{version: 0.1.0}并写一个 Django 测试断言状态码、响应类型和字段值。下一篇会在这个项目上创建 Category 和 Product 模型并解释迁移文件到底做了什么。项目增量商城目录和第一个请求本篇目标不是记住 startproject 命令而是理解 settings、urls、app 和模板各自负责什么。创建 shop app 后把首页路由接到一个明确的 view再用 Django test client 验收状态码。fromdjango.httpimportHttpResponsedefhome(request):returnHttpResponse(shop is running)验收GET /返回 200若出现 404依次检查项目 urls 是否 include shop.urls、路径是否带结尾斜杠以及应用是否加入 INSTALLED_APPS。课后练习增加/healthJSON 响应下一篇创建商品模型。十、把第一次请求做成可维护的接口健康检查不应返回一段随意文本推荐固定 JSON 契约并写测试fromdjango.httpimportJsonResponsedefhealth(request):returnJsonResponse({status:ok,service:django-shop,version:0.1.0})fromdjango.testimportTestCaseclassHealthTests(TestCase):deftest_health_contract(self):responseself.client.get(/api/health/)self.assertEqual(response.status_code,200)self.assertEqual(response.json()[status],ok)self.assertEqual(response[Content-Type],application/json)manage.py check检查配置migrate管理数据库结构runserver才是启动 HTTP 服务三者分工不同。开发阶段先让/api/health/稳定后面每次增加模型、Serializer 或事务都可以用它区分“进程坏了”与“业务依赖坏了”。本篇练习完成后下一篇会在同一项目中加入 Category/Product并用迁移而不是手工建表。本篇结束完整模块文件下面是交付项目中真实存在的完整文件 django-shop/config/urls.py。它覆盖本篇新增逻辑以及前文已经完成的依赖代码复制单个函数会丢失上下文因此这里提供整份文件。 URL configuration for config project. The urlpatterns list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/5.2/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path(, views.home, namehome) Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path(, Home.as_view(), namehome) Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path(blog/, include(blog.urls)) fromdjango.contribimportadminfromdjango.urlsimportinclude,path urlpatterns[path(admin/,admin.site.urls),path(api/,include(shop.urls)),]
返回列表