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

Could not load content