1. Django 简介与环境搭建
什么是 Django?
Django 是一个高级 Python Web 框架,它鼓励快速开发和干净、实用的设计。它遵循 MVC(模型-视图-控制器)架构模式,但在 Django 中被称为 MVT(模型-模板-视图)。
核心特性:
- 强大的 ORM(对象关系映射)
- 自动化的管理界面
- 优雅的 URL 设计
- 模板系统
- 缓存框架
- 国际化支持
环境安装与配置
python
# 安装 Django
pip install django
# 验证安装
python -m django --version
# 创建项目
django-admin startproject myproject
cd myproject
# 创建应用
python manage.py startapp myapp
项目结构解析
myproject/
├── manage.py # 项目管理脚本
├── myproject/ # 项目配置目录
│ ├── __init__.py
│ ├── settings.py # 项目设置
│ ├── urls.py # URL 配置
│ └── wsgi.py # WSGI 入口
└── myapp/ # 应用目录
├── __init__.py
├── admin.py # 管理后台配置
├── apps.py # 应用配置
├── models.py # 数据模型
├── tests.py # 测试用例
└── views.py # 视图函数
2. 视图 (Views) 基础
函数视图
python
# myapp/views.py
from django.http import HttpResponse
from django.shortcuts import render
def hello_world(request):
"""简单的视图函数示例"""
return HttpResponse("Hello, World!")
def welcome_page(request):
"""带模板的视图函数"""
context = {
'title': '欢迎页面',
'message': '欢迎来到Django世界!',
'user': '访客'
}
return render(request, 'welcome.html', context)
def user_profile(request, username):
"""带参数的视图函数"""
return HttpResponse(f"用户 {username} 的个人主页")
类视图
python
# myapp/views.py
from django.views import View
from django.http import JsonResponse
class BookListView(View):
"""书籍列表类视图"""
def get(self, request):
books = [
{'title': 'Python编程', 'author': 'John Doe'},
{'title': 'Django实战', 'author': 'Jane Smith'}
]
return JsonResponse(books, safe=False)
def post(self, request):
# 处理POST请求
return JsonResponse({'status': 'created'})
class ProductDetailView(View):
"""产品详情类视图"""
def get(self, request, product_id):
product = {
'id': product_id,
'name': f'产品{product_id}',
'price': 99.99
}
return JsonResponse(product)
3. URL 配置
基础 URL 路由
python
# myproject/urls.py (项目级URL配置)
from django.contrib import admin
from django.urls import path, include
from myapp import views
urlpatterns = [
path('admin/', admin.site.urls),
path('hello/', views.hello_world),
path('welcome/', views.welcome_page),
path('user/<str:username>/', views.user_profile),
path('api/', include('myapp.urls')), # 包含应用级URL
]
# myapp/urls.py (应用级URL配置)
from django.urls import path
from . import views
urlpatterns = [
path('books/', views.BookListView.as_view()),
path('products/<int:product_id>/', views.ProductDetailView.as_view()),
]
URL 参数类型
python
# URL 模式示例
"""
path('articles/<int:year>/', views.year_archive), # 整数参数
path('articles/<int:year>/<int:month>/', views.month_archive),
path('articles/<slug:slug>/', views.article_detail), # 字母数字连字符
path('users/<str:username>/', views.user_profile), # 字符串
path('pages/<path:path>/', views.page_detail), # 包含斜杠的路径
"""
4. 模板系统基础
模板语法
html
<!-- templates/welcome.html -->
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ message }}</h1>
<!-- 条件判断 -->
{% if user %}
<p>欢迎, {{ user }}!</p>
{% else %}
<p>请先登录</p>
{% endif %}
<!-- 循环 -->
<ul>
{% for item in items %}
<li>{{ forloop.counter }}. {{ item.name }}</li>
{% empty %}
<li>暂无数据</li>
{% endfor %}
</ul>
<!-- 过滤器 -->
<p>{{ content|lower }}</p>
<p>{{ date|date:"Y-m-d" }}</p>
<p>{{ text|truncatewords:10 }}</p>
<!-- 模板继承 -->
{% extends "base.html" %}
{% block content %}
<h2>页面内容</h2>
{% endblock %}
</body>
</html>
基础模板
html
<!-- templates/base.html -->
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}默认标题{% endblock %}</title>
<style>
.header { background: #f0f0f0; padding: 20px; }
.content { padding: 20px; }
.footer { background: #333; color: white; padding: 10px; }
</style>
</head>
<body>
<div class="header">
<h1>我的网站</h1>
<nav>
<a href="/">首页</a> |
<a href="/about/">关于</a> |
<a href="/contact/">联系</a>
</nav>
</div>
<div class="content">
{% block content %}
<!-- 子模板内容将插入这里 -->
{% endblock %}
</div>
<div class="footer">
<p>© 2024 我的网站</p>
</div>
</body>
</html>
5. 简单的数据模型
基础模型定义
python
# myapp/models.py
from django.db import models
class Category(models.Model):
"""分类模型"""
name = models.CharField(max_length=100, verbose_name='分类名称')
description = models.TextField(blank=True, verbose_name='描述')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Meta:
db_table = 'categories'
verbose_name = '分类'
verbose_name_plural = '分类'
def __str__(self):
return self.name
class Product(models.Model):
"""产品模型"""
# 字段类型示例
name = models.CharField(max_length=200, verbose_name='产品名称')
price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='价格')
description = models.TextField(blank=True, verbose_name='描述')
is_available = models.BooleanField(default=True, verbose_name='是否可用')
category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name='分类')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
ordering = ['-created_at']
verbose_name = '产品'
verbose_name_plural = '产品'
def __str__(self):
return f"{self.name} - ¥{self.price}"
数据库迁移
bash
# 生成迁移文件
python manage.py makemigrations
# 查看生成的SQL
python manage.py sqlmigrate myapp 0001
# 执行迁移
python manage.py migrate
# 查看迁移状态
python manage.py showmigrations
6. 管理后台基础
python
# myapp/admin.py
from django.contrib import admin
from .models import Category, Product
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
"""分类管理配置"""
list_display = ['name', 'created_at'] # 列表显示字段
list_filter = ['created_at'] # 过滤器
search_fields = ['name'] # 搜索字段
ordering = ['-created_at'] # 排序
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
"""产品管理配置"""
list_display = ['name', 'price', 'category', 'is_available', 'created_at']
list_filter = ['category', 'is_available', 'created_at']
search_fields = ['name', 'description']
list_editable = ['price', 'is_available'] # 可直接编辑的字段
date_hierarchy = 'created_at' # 日期层级导航
# 字段分组显示
fieldsets = [
('基础信息', {
'fields': ['name', 'category', 'price']
}),
('详细信息', {
'fields': ['description', 'is_available'],
'classes': ['collapse'] # 可折叠
}),
]
7. 综合示例:简单的博客系统
python
# myapp/models.py
class Post(models.Model):
"""博客文章模型"""
title = models.CharField(max_length=200, verbose_name='标题')
content = models.TextField(verbose_name='内容')
author = models.CharField(max_length=100, verbose_name='作者')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
is_published = models.BooleanField(default=False, verbose_name='是否发布')
class Meta:
ordering = ['-created_at']
verbose_name = '文章'
verbose_name_plural = '文章'
def __str__(self):
return self.title
# myapp/views.py
def post_list(request):
"""文章列表视图"""
posts = Post.objects.filter(is_published=True)
return render(request, 'blog/post_list.html', {'posts': posts})
def post_detail(request, post_id):
"""文章详情视图"""
post = get_object_or_404(Post, id=post_id, is_published=True)
return render(request, 'blog/post_detail.html', {'post': post})
# myapp/urls.py
urlpatterns = [
path('posts/', post_list, name='post_list'),
path('posts/<int:post_id>/', post_detail, name='post_detail'),
]
html
<!-- templates/blog/post_list.html -->
{% extends "base.html" %}
{% block title %}博客文章列表{% endblock %}
{% block content %}
<h1>博客文章</h1>
{% for post in posts %}
<article>
<h2><a href="{% url 'post_detail' post.id %}">{{ post.title }}</a></h2>
<p>作者: {{ post.author }} | 发布时间: {{ post.created_at|date:"Y-m-d" }}</p>
<p>{{ post.content|truncatewords:30 }}</p>
</article>
<hr>
{% empty %}
<p>暂无文章</p>
{% endfor %}
{% endblock %}