Python开发从入门到精通:Web框架Django实战

Python开发从入门到精通:Web框架Django实战

《Python开发从入门到精通》设计指南第十七篇:Web框架Django实战

在这里插入图片描述

一、学习目标与重点

💡 学习目标:掌握Django框架的核心功能,包括模型、视图、模板、表单、认证、权限管理等;理解Django的MVC架构;通过实战案例开发一个完整的Web应用。
⚠️ 学习重点:Django项目结构、模型定义、视图函数、模板渲染、表单处理、用户认证、权限管理、数据库操作。

17.1 Django框架概述

17.1.1 什么是Django

Django是一个开源的Python Web框架,遵循MVC(Model-View-Controller)架构,提供了完整的Web开发解决方案,包括数据库操作、表单处理、用户认证、权限管理等。

17.1.2 Django的特点

  • 快速开发:提供了丰富的内置功能,如ORM、模板引擎、表单处理等,减少了开发时间。
  • 安全性:内置了CSRF保护、XSS防护、SQL注入防护等安全措施。
  • 可扩展性:支持插件化开发,有大量的第三方库和应用。
  • 文档完善:提供了详细的官方文档和示例代码。

17.1.3 Django的安装

pip install django 

17.2 创建Django项目

17.2.1 创建项目

django-admin startproject myproject 

17.2.2 创建应用

cd myproject python manage.py startapp myapp 

17.2.3 项目结构

myproject/ ├── manage.py ├── myapp/ │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations/ │ ├── models.py │ ├── tests.py │ └── views.py └── myproject/ ├── __init__.py ├── asgi.py ├── settings.py ├── urls.py └── wsgi.py 

17.3 模型定义

17.3.1 定义模型

# myapp/models.pyfrom django.db import models classProduct(models.Model): name = models.CharField(max_length=100) price = models.DecimalField(max_digits=10, decimal_places=2) description = models.TextField() created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True)def__str__(self):return self.name 

17.3.2 迁移数据库

python manage.py makemigrations python manage.py migrate 

17.4 视图函数

17.4.1 定义视图函数

# myapp/views.pyfrom django.shortcuts import render, get_object_or_404, redirect from myapp.models import Product from myapp.forms import ProductForm defproduct_list(request): products = Product.objects.all()return render(request,'myapp/product_list.html',{'products': products})defproduct_detail(request, product_id): product = get_object_or_404(Product, pk=product_id)return render(request,'myapp/product_detail.html',{'product': product})defproduct_create(request):if request.method =='POST': form = ProductForm(request.POST)if form.is_valid(): form.save()return redirect('product_list')else: form = ProductForm()return render(request,'myapp/product_form.html',{'form': form})defproduct_update(request, product_id): product = get_object_or_404(Product, pk=product_id)if request.method =='POST': form = ProductForm(request.POST, instance=product)if form.is_valid(): form.save()return redirect('product_list')else: form = ProductForm(instance=product)return render(request,'myapp/product_form.html',{'form': form})defproduct_delete(request, product_id): product = get_object_or_404(Product, pk=product_id)if request.method =='POST': product.delete()return redirect('product_list')return render(request,'myapp/product_delete.html',{'product': product})

17.5 表单处理

17.5.1 定义表单

# myapp/forms.pyfrom django import forms from myapp.models import Product classProductForm(forms.ModelForm):classMeta: model = Product fields =['name','price','description']

17.6 模板渲染

17.6.1 定义模板

<!-- myapp/templates/myapp/base.html --><!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>{% block title %}产品管理系统{% endblock %}</title><linkrel="stylesheet"href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"></head><body><navclass="navbar navbar-expand-lg navbar-light bg-light"><aclass="navbar-brand"href="{% url 'product_list' %}">产品管理系统</a><divclass="collapse navbar-collapse"><ulclass="navbar-nav mr-auto"><liclass="nav-item"><aclass="nav-link"href="{% url 'product_list' %}">产品列表</a></li><liclass="nav-item"><aclass="nav-link"href="{% url 'product_create' %}">添加产品</a></li></ul></div></nav><divclass="container mt-4"> {% block content %}{% endblock %} </div><scriptsrc="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script></body></html>
<!-- myapp/templates/myapp/product_list.html --> {% extends 'myapp/base.html' %} {% block title %}产品列表{% endblock %} {% block content %} <h1>产品列表</h1><tableclass="table table-striped"><thead><tr><th>名称</th><th>价格</th><th>描述</th><th>创建时间</th><th>操作</th></tr></thead><tbody> {% for product in products %} <tr><td>{{ product.name }}</td><td>{{ product.price }}</td><td>{{ product.description }}</td><td>{{ product.created_at }}</td><td><ahref="{% url 'product_detail' product.id %}"class="btn btn-primary btn-sm">查看</a><ahref="{% url 'product_update' product.id %}"class="btn btn-secondary btn-sm">编辑</a><ahref="{% url 'product_delete' product.id %}"class="btn btn-danger btn-sm">删除</a></td></tr> {% endfor %} </tbody></table> {% endblock %} 
<!-- myapp/templates/myapp/product_detail.html --> {% extends 'myapp/base.html' %} {% block title %}产品详情{% endblock %} {% block content %} <h1>产品详情</h1><divclass="card"><divclass="card-body"><h5class="card-title">{{ product.name }}</h5><pclass="card-text">{{ product.description }}</p><pclass="card-text">价格:{{ product.price }}</p><pclass="card-text">创建时间:{{ product.created_at }}</p><pclass="card-text">更新时间:{{ product.updated_at }}</p><ahref="{% url 'product_update' product.id %}"class="btn btn-secondary">编辑</a><ahref="{% url 'product_delete' product.id %}"class="btn btn-danger">删除</a></div></div> {% endblock %} 
<!-- myapp/templates/myapp/product_form.html --> {% extends 'myapp/base.html' %} {% block title %}添加/编辑产品{% endblock %} {% block content %} <h1>{% if form.instance.pk %}编辑产品{% else %}添加产品{% endif %}</h1><formmethod="post"> {% csrf_token %} {{ form.as_p }} <buttontype="submit"class="btn btn-primary">保存</button><ahref="{% url 'product_list' %}"class="btn btn-secondary">取消</a></form> {% endblock %} 
<!-- myapp/templates/myapp/product_delete.html --> {% extends 'myapp/base.html' %} {% block title %}删除产品{% endblock %} {% block content %} <h1>删除产品</h1><p>你确定要删除产品 "{{ product.name }}" 吗?</p><formmethod="post"> {% csrf_token %} <buttontype="submit"class="btn btn-danger">确认删除</button><ahref="{% url 'product_list' %}"class="btn btn-secondary">取消</a></form> {% endblock %} 

17.7 路由配置

17.7.1 应用路由

# myapp/urls.pyfrom django.urls import path from myapp import views urlpatterns =[ path('', views.product_list, name='product_list'), path('product/<int:product_id>/', views.product_detail, name='product_detail'), path('product/create/', views.product_create, name='product_create'), path('product/<int:product_id>/update/', views.product_update, name='product_update'), path('product/<int:product_id>/delete/', views.product_delete, name='product_delete'),]

17.7.2 项目路由

# myproject/urls.pyfrom django.contrib import admin from django.urls import path, include urlpatterns =[ path('admin/', admin.site.urls), path('', include('myapp.urls')),]

17.8 用户认证与权限管理

17.8.1 配置认证系统

# myproject/settings.py INSTALLED_APPS =['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','myapp',] MIDDLEWARE =['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',]

17.8.2 创建用户

python manage.py createsuperuser 

17.8.3 权限管理

# myapp/admin.pyfrom django.contrib import admin from myapp.models import Product @admin.register(Product)classProductAdmin(admin.ModelAdmin): list_display =['name','price','description','created_at','updated_at'] list_filter =['created_at'] search_fields =['name','description']

17.9 静态文件管理

17.9.1 配置静态文件

# myproject/settings.py STATIC_URL ='/static/' STATICFILES_DIRS =[ os.path.join(BASE_DIR,'static'),]

17.9.2 加载静态文件

<!-- myapp/templates/myapp/base.html --> {% load static %} <!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>{% block title %}产品管理系统{% endblock %}</title><linkrel="stylesheet"href="{% static 'css/bootstrap.min.css' %}"></head><body> ... <scriptsrc="{% static 'js/bootstrap.bundle.min.js' %}"></script></body></html>

17.10 实战案例:产品管理系统

17.10.1 需求分析

开发一个产品管理系统,支持以下功能:

  • 产品的添加、删除、修改、查询。
  • 用户的注册、登录、退出。
  • 产品的分类管理。
  • 产品的搜索功能。

17.10.2 代码实现

17.10.2.1 模型定义
# myapp/models.pyfrom django.db import models from django.contrib.auth.models import User classCategory(models.Model): name = models.CharField(max_length=100) description = models.TextField() created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True)def__str__(self):return self.name classProduct(models.Model): name = models.CharField(max_length=100) price = models.DecimalField(max_digits=10, decimal_places=2) description = models.TextField() category = models.ForeignKey(Category, on_delete=models.CASCADE) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True)def__str__(self):return self.name 
17.10.2.2 表单定义
# myapp/forms.pyfrom django import forms from myapp.models import Product, Category classCategoryForm(forms.ModelForm):classMeta: model = Category fields =['name','description']classProductForm(forms.ModelForm):classMeta: model = Product fields =['name','price','description','category']
17.10.2.3 视图函数
# myapp/views.pyfrom django.shortcuts import render, get_object_or_404, redirect from myapp.models import Product, Category from myapp.forms import ProductForm, CategoryForm from django.contrib.auth.decorators import login_required defcategory_list(request): categories = Category.objects.all()return render(request,'myapp/category_list.html',{'categories': categories})defcategory_detail(request, category_id): category = get_object_or_404(Category, pk=category_id) products = category.product_set.all()return render(request,'myapp/category_detail.html',{'category': category,'products': products})@login_requireddefcategory_create(request):if request.method =='POST': form = CategoryForm(request.POST)if form.is_valid(): form.save()return redirect('category_list')else: form = CategoryForm()return render(request,'myapp/category_form.html',{'form': form})@login_requireddefcategory_update(request, category_id): category = get_object_or_404(Category, pk=category_id)if request.method =='POST': form = CategoryForm(request.POST, instance=category)if form.is_valid(): form.save()return redirect('category_list')else: form = CategoryForm(instance=category)return render(request,'myapp/category_form.html',{'form': form})@login_requireddefcategory_delete(request, category_id): category = get_object_or_404(Category, pk=category_id)if request.method =='POST': category.delete()return redirect('category_list')return render(request,'myapp/category_delete.html',{'category': category})defproduct_list(request): search_query = request.GET.get('search','') products = Product.objects.filter(name__icontains=search_query)return render(request,'myapp/product_list.html',{'products': products,'search_query': search_query})defproduct_detail(request, product_id): product = get_object_or_404(Product, pk=product_id)return render(request,'myapp/product_detail.html',{'product': product})@login_requireddefproduct_create(request):if request.method =='POST': form = ProductForm(request.POST)if form.is_valid(): form.save()return redirect('product_list')else: form = ProductForm()return render(request,'myapp/product_form.html',{'form': form})@login_requireddefproduct_update(request, product_id): product = get_object_or_404(Product, pk=product_id)if request.method =='POST': form = ProductForm(request.POST, instance=product)if form.is_valid(): form.save()return redirect('product_list')else: form = ProductForm(instance=product)return render(request,'myapp/product_form.html',{'form': form})@login_requireddefproduct_delete(request, product_id): product = get_object_or_404(Product, pk=product_id)if request.method =='POST': product.delete()return redirect('product_list')return render(request,'myapp/product_delete.html',{'product': product})
17.10.2.4 路由配置
# myapp/urls.pyfrom django.urls import path from myapp import views urlpatterns =[ path('', views.product_list, name='product_list'), path('category/', views.category_list, name='category_list'), path('category/<int:category_id>/', views.category_detail, name='category_detail'), path('category/create/', views.category_create, name='category_create'), path('category/<int:category_id>/update/', views.category_update, name='category_update'), path('category/<int:category_id>/delete/', views.category_delete, name='category_delete'), path('product/<int:product_id>/', views.product_detail, name='product_detail'), path('product/create/', views.product_create, name='product_create'), path('product/<int:product_id>/update/', views.product_update, name='product_update'), path('product/<int:product_id>/delete/', views.product_delete, name='product_delete'),]
17.10.2.5 模板定义
<!-- myapp/templates/myapp/category_list.html --> {% extends 'myapp/base.html' %} {% block title %}分类列表{% endblock %} {% block content %} <h1>分类列表</h1><tableclass="table table-striped"><thead><tr><th>名称</th><th>描述</th><th>创建时间</th><th>操作</th></tr></thead><tbody> {% for category in categories %} <tr><td>{{ category.name }}</td><td>{{ category.description }}</td><td>{{ category.created_at }}</td><td><ahref="{% url 'category_detail' category.id %}"class="btn btn-primary btn-sm">查看</a><ahref="{% url 'category_update' category.id %}"class="btn btn-secondary btn-sm">编辑</a><ahref="{% url 'category_delete' category.id %}"class="btn btn-danger btn-sm">删除</a></td></tr> {% endfor %} </tbody></table><ahref="{% url 'category_create' %}"class="btn btn-primary">添加分类</a> {% endblock %} 
<!-- myapp/templates/myapp/category_detail.html --> {% extends 'myapp/base.html' %} {% block title %}分类详情{% endblock %} {% block content %} <h1>{{ category.name }}</h1><p>{{ category.description }}</p><h2>产品列表</h2><tableclass="table table-striped"><thead><tr><th>名称</th><th>价格</th><th>描述</th><th>创建时间</th><th>操作</th></tr></thead><tbody> {% for product in products %} <tr><td>{{ product.name }}</td><td>{{ product.price }}</td><td>{{ product.description }}</td><td>{{ product.created_at }}</td><td><ahref="{% url 'product_detail' product.id %}"class="btn btn-primary btn-sm">查看</a><ahref="{% url 'product_update' product.id %}"class="btn btn-secondary btn-sm">编辑</a><ahref="{% url 'product_delete' product.id %}"class="btn btn-danger btn-sm">删除</a></td></tr> {% endfor %} </tbody></table><ahref="{% url 'product_create' %}"class="btn btn-primary">添加产品</a> {% endblock %} 
<!-- myapp/templates/myapp/category_form.html --> {% extends 'myapp/base.html' %} {% block title %}添加/编辑分类{% endblock %} {% block content %} <h1>{% if form.instance.pk %}编辑分类{% else %}添加分类{% endif %}</h1><formmethod="post"> {% csrf_token %} {{ form.as_p }} <buttontype="submit"class="btn btn-primary">保存</button><ahref="{% url 'category_list' %}"class="btn btn-secondary">取消</a></form> {% endblock %} 
<!-- myapp/templates/myapp/category_delete.html --> {% extends 'myapp/base.html' %} {% block title %}删除分类{% endblock %} {% block content %} <h1>删除分类</h1><p>你确定要删除分类 "{{ category.name }}" 吗?</p><formmethod="post"> {% csrf_token %} <buttontype="submit"class="btn btn-danger">确认删除</button><ahref="{% url 'category_list' %}"class="btn btn-secondary">取消</a></form> {% endblock %} 
17.10.2.6 搜索功能
<!-- myapp/templates/myapp/product_list.html --> {% extends 'myapp/base.html' %} {% block title %}产品列表{% endblock %} {% block content %} <h1>产品列表</h1><formmethod="get"><divclass="form-group"><inputtype="text"name="search"value="{{ search_query }}"class="form-control"placeholder="搜索产品名称"></div><buttontype="submit"class="btn btn-primary">搜索</button></form><tableclass="table table-striped mt-4"><thead><tr><th>名称</th><th>价格</th><th>描述</th><th>分类</th><th>创建时间</th><th>操作</th></tr></thead><tbody> {% for product in products %} <tr><td>{{ product.name }}</td><td>{{ product.price }}</td><td>{{ product.description }}</td><td>{{ product.category.name }}</td><td>{{ product.created_at }}</td><td><ahref="{% url 'product_detail' product.id %}"class="btn btn-primary btn-sm">查看</a><ahref="{% url 'product_update' product.id %}"class="btn btn-secondary btn-sm">编辑</a><ahref="{% url 'product_delete' product.id %}"class="btn btn-danger btn-sm">删除</a></td></tr> {% endfor %} </tbody></table><ahref="{% url 'product_create' %}"class="btn btn-primary">添加产品</a> {% endblock %} 

17.10.3 实施过程

  1. 创建Django项目和应用。
  2. 定义模型、表单、视图函数。
  3. 配置路由和模板。
  4. 迁移数据库。
  5. 创建超级用户。
  6. 运行开发服务器。

17.10.4 最终效果

通过产品管理系统,我们可以实现以下功能:

  • 产品的添加、删除、修改、查询。
  • 用户的注册、登录、退出。
  • 产品的分类管理。
  • 产品的搜索功能。

总结

✅ 本文详细介绍了Django框架的核心功能,包括模型、视图、模板、表单、用户认证、权限管理等;通过实战案例开发了一个完整的产品管理系统。
✅ 建议读者在学习过程中多练习,通过编写代码加深对知识点的理解。

Read more

RabbitMQ如何成为分布式系统的“神经中枢“?——从安装部署到C++调用实战的完整流程,带你体验它的奥妙所在!​

RabbitMQ如何成为分布式系统的“神经中枢“?——从安装部署到C++调用实战的完整流程,带你体验它的奥妙所在!​

文章目录 * 本篇摘要 * ①·RabbitMq(轻量级消息队列中间件) 介绍 * RabbitMQ 是什么? * 核心功能与特点 * 1. **核心功能** * 2. **核心优势** * RabbitMQ 的核心概念 * 1. **生产者(Producer)** * 2. **消费者(Consumer)** * 3. **队列(Queue)** * 4. **交换机(Exchange)** * 5. **绑定(Binding)** * 工作流程(以 Direct 交换机为例) * 常见应用场景 * RabbitMQ 与相关技术对比 * 图像理解 * 总结一句话 * ②·RabbitMq 安装教程 * RabbitMq安装 * **1. 安装 RabbitMQ** * **2. 启动 & 检查状态** * **3. 创建管理员用户(

By Ne0inhk
SkyWalking - Kafka _ RabbitMQ 消息链路追踪支持

SkyWalking - Kafka _ RabbitMQ 消息链路追踪支持

👋 大家好,欢迎来到我的技术博客! 📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。 🎯 本文将围绕SkyWalking这个话题展开,希望能为你带来一些启发或实用的参考。 🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获! 文章目录 * SkyWalking - Kafka / RabbitMQ 消息链路追踪支持 🚀 * 为什么需要消息链路追踪?🤔 * SkyWalking 核心概念回顾 🔍 * Kafka 链路追踪支持 🐘 * 1. 自动探针(推荐)✅ * 前提条件 * 工作原理 * Java 代码示例(无需修改业务代码!) * 验证追踪效果 * 2. 手动埋点(高级场景)🛠️ * 添加依赖 * 手动注入上下文(Producer) * 手动提取上下文(Consumer) * RabbitMQ 链路追踪支持 🐇 * 工作原理 * Java 代码

By Ne0inhk
KWDB 运维实战:拒绝数据孤岛!用 SQL 打通 Metrics 与 CMDB 的“任督二脉”

KWDB 运维实战:拒绝数据孤岛!用 SQL 打通 Metrics 与 CMDB 的“任督二脉”

在互联网大厂,服务器监控(AIOps)是基础设施的命脉。一旦核心数据库或网关宕机,每分钟的损失可能高达数百万。 传统的监控方案(如 Zabbix、Prometheus)在面对海量指标时各有痛点:Zabbix 擅长告警但历史数据存储能力弱;Prometheus 查询语言(PromQL)学习曲线陡峭且不易与业务数据(如 CMDB)进行关联分析。 运维人员真正需要的是:既能像 Prometheus 一样吞吐海量时序数据,又能像 MySQL 一样用标准 SQL 进行复杂关联查询。 本文将带你体验如何用 KWDB 3.1.0 搭建一个轻量级但高性能的 服务器监控系统,用一个数据库搞定“指标存储”与“资产管理”。 * 场景设定: 监控 500 台服务器的 CPU、内存、磁盘 IO 和网络流量。 * 核心挑战:

By Ne0inhk
直击复杂 SQL 瓶颈:基于代价的连接条件下推技术落地

直击复杂 SQL 瓶颈:基于代价的连接条件下推技术落地

一、引言 在数据库理论的学习过程中,我们常常接触到简洁优美的SQL示例——单表查询、简单连接、基础过滤,这些案例清晰地展示了关系代数的基本原理。然而,当我们步入真实的业务系统,面对的SQL语句往往如同缠绕的线团:公用表表达式(CTE)层层嵌套,子查询彼此交织,窗口函数与聚集计算随处可见。 这种复杂性并非开发人员的炫技,而是业务逻辑的自然映射。遗憾的是,这种为提升可读性而组织的SQL结构,却给查询优化器带来了严峻考验。在众多性能瓶颈中,有一个问题尤为突出:高选择性的连接条件无法穿透复杂的子查询结构,导致数据过滤发生在错误的时间点。本文将深入探讨这一问题的本质,并介绍一种基于代价模型的连接条件下推解决方案,展示如何让优化器既懂“安全”,又知“成本”。 二、性能困境:过滤迟到的代价 2.1 真实场景的切面分析 在大量客户业务系统中,一种常见的SQL编写模式反复出现:开发人员习惯先在子查询或CTE中完成复杂的预处理逻辑——去重、排序、窗口计算,然后再将这些预处理结果与其它表进行连接,最后施加过滤条件。从业务语义角度看,这种写法清晰自然;但从执行效率角度看,却暗藏危机。 考虑

By Ne0inhk