Django框架入门:Python Web开发全攻略
2026/7/19 11:22:25 网站建设 项目流程

1. Django框架概述:Python Web开发的瑞士军刀

Django作为Python生态中最负盛名的全栈Web框架,自2005年诞生以来就以其"开箱即用"的特性闻名。这个采用MTV架构模式的框架,本质上是一个高效的工具集合,包含:

  • 对象关系映射器(ORM):用Python类定义数据模型,自动生成数据库表结构
  • 模板引擎:分离业务逻辑与展示层,支持模板继承机制
  • 表单处理:内置CSRF防护、数据验证和清理功能
  • 管理后台:自动生成的内容管理系统,节省80%的CRUD开发时间
  • 路由系统:URLconf配置将URL模式映射到视图函数
  • 认证系统:用户、组、权限管理一应俱全

实战经验:在中小型项目中使用Django Admin可以直接获得生产可用的后台,这是其他框架难以比拟的优势。我曾用3天时间基于Admin定制出一个出版社图书管理系统,而传统开发至少需要2周。

2. 环境搭建与项目初始化

2.1 开发环境配置

推荐使用Python 3.8+版本,通过venv创建隔离环境:

python -m venv django_env source django_env/bin/activate # Linux/Mac django_env\Scripts\activate.bat # Windows pip install django==4.2

2.2 项目脚手架生成

执行以下命令创建项目骨架:

django-admin startproject myproject cd myproject python manage.py startapp myapp

关键目录结构解析:

myproject/ ├── manage.py # 项目管理脚本 ├── myproject/ # 全局配置目录 │ ├── __init__.py │ ├── settings.py # 数据库/中间件/模板等配置 │ ├── urls.py # 主路由配置 │ └── wsgi.py # WSGI入口 └── myapp/ # 应用目录 ├── migrations/ # 数据库迁移文件 ├── admin.py # Admin配置 ├── models.py # 数据模型 ├── views.py # 业务逻辑 └── templates/ # 模板文件

2.3 基础配置要点

在settings.py中必须关注的配置项:

INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'myapp', # 新增应用 ] DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } } STATIC_URL = '/static/' # 静态文件URL前缀 STATICFILES_DIRS = [BASE_DIR / "static"] # 静态文件目录

3. 核心组件深度解析

3.1 模型层(Model)设计

模型定义示例(myapp/models.py):

from django.db import models from django.core.validators import MinLengthValidator class Author(models.Model): name = models.CharField(max_length=100) email = models.EmailField(unique=True) bio = models.TextField( validators=[MinLengthValidator(10)], help_text="至少10个字符的作者简介" ) def __str__(self): return self.name class Book(models.Model): title = models.CharField(max_length=200) author = models.ForeignKey(Author, on_delete=models.CASCADE) publish_date = models.DateField() price = models.DecimalField(max_digits=6, decimal_places=2) stock = models.PositiveIntegerField(default=0) class Meta: ordering = ['-publish_date'] indexes = [ models.Index(fields=['title']), ]

生成迁移并同步数据库:

python manage.py makemigrations python manage.py migrate

3.2 视图层(View)开发

函数视图与类视图对比示例:

# 函数视图 from django.shortcuts import render, get_object_or_404 from .models import Book def book_list(request): books = Book.objects.filter(stock__gt=0) return render(request, 'book/list.html', {'books': books}) # 类视图 from django.views.generic import ListView, DetailView class BookListView(ListView): model = Book template_name = 'book/list.html' context_object_name = 'books' paginate_by = 10 def get_queryset(self): return Book.objects.filter(stock__gt=0) class BookDetailView(DetailView): model = Book template_name = 'book/detail.html'

3.3 模板系统实战

模板继承示例(templates/base.html):

<!DOCTYPE html> <html> <head> <title>{% block title %}默认标题{% endblock %}</title> {% block css %}{% endblock %} </head> <body> <nav>导航栏内容</nav> <main> {% block content %}{% endblock %} </main> <footer>页脚信息</footer> {% block js %}{% endblock %} </body> </html>

子模板示例(templates/book/list.html):

{% extends "base.html" %} {% block title %}图书列表{% endblock %} {% block content %} <ul> {% for book in books %} <li> <a href="{{ book.get_absolute_url }}">{{ book.title }}</a> - {{ book.author.name }} </li> {% empty %} <li>暂无库存图书</li> {% endfor %} </ul> {% endblock %}

4. Django Admin深度定制

4.1 基础配置

在myapp/admin.py中注册模型:

from django.contrib import admin from .models import Author, Book @admin.register(Book) class BookAdmin(admin.ModelAdmin): list_display = ('title', 'author', 'price', 'stock') list_filter = ('author', 'publish_date') search_fields = ('title', 'author__name') raw_id_fields = ('author',) date_hierarchy = 'publish_date' ordering = ('-publish_date',) admin.site.register(Author)

4.2 高级定制技巧

  1. 自定义表单验证:
class BookAdminForm(forms.ModelForm): class Meta: model = Book fields = '__all__' def clean_price(self): price = self.cleaned_data['price'] if price < 0: raise forms.ValidationError("价格不能为负数") return price class BookAdmin(admin.ModelAdmin): form = BookAdminForm
  1. 添加自定义操作:
def make_available(modeladmin, request, queryset): queryset.update(stock=100) make_available.short_description = "补货100本" class BookAdmin(admin.ModelAdmin): actions = [make_available]

5. 实战:构建RESTful API

5.1 DRF基础配置

安装DRF并创建序列化器:

pip install djangorestframework

在settings.py中添加:

INSTALLED_APPS += ['rest_framework']

创建序列化器(myapp/serializers.py):

from rest_framework import serializers from .models import Book class BookSerializer(serializers.ModelSerializer): author_name = serializers.CharField(source='author.name', read_only=True) class Meta: model = Book fields = ['id', 'title', 'author', 'author_name', 'price', 'stock']

5.2 视图集配置

from rest_framework import viewsets from .models import Book from .serializers import BookSerializer class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer filterset_fields = ['author', 'stock'] search_fields = ['title', 'author__name'] ordering_fields = ['price', 'publish_date']

5.3 路由配置

from django.urls import path, include from rest_framework.routers import DefaultRouter from myapp import views router = DefaultRouter() router.register(r'books', views.BookViewSet) urlpatterns = [ path('api/', include(router.urls)), path('api-auth/', include('rest_framework.urls')), ]

6. 部署上线关键步骤

6.1 生产环境配置

修改settings.py:

DEBUG = False ALLOWED_HOSTS = ['yourdomain.com', 'localhost'] STATIC_ROOT = BASE_DIR / 'staticfiles'

安装必要依赖:

pip install gunicorn psycopg2-binary

6.2 Nginx配置示例

server { listen 80; server_name yourdomain.com; location /static/ { alias /path/to/staticfiles; } location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }

6.3 启动服务

使用Gunicorn启动:

gunicorn --workers 3 --bind 127.0.0.1:8000 myproject.wsgi:application

7. 性能优化实战技巧

  1. 查询优化:
# 反例:N+1查询问题 books = Book.objects.all() for book in books: print(book.author.name) # 每次循环都查询数据库 # 正例:使用select_related books = Book.objects.select_related('author').all()
  1. 缓存策略:
from django.core.cache import cache def get_books(): books = cache.get('all_books') if not books: books = list(Book.objects.all()) cache.set('all_books', books, timeout=3600) return books
  1. 异步任务: 安装Celery:
pip install celery redis

创建任务(myapp/tasks.py):

from celery import shared_task from django.core.mail import send_mail @shared_task def send_notification_email(subject, message, recipient): send_mail( subject, message, 'admin@example.com', [recipient], fail_silently=False, )

8. 安全防护最佳实践

  1. CSRF防护:
<form method="post"> {% csrf_token %} <!-- 表单内容 --> </form>
  1. XSS防护:
from django.utils.html import escape def user_profile(request): user_input = request.GET.get('q', '') # 自动转义HTML return render(request, 'profile.html', {'data': escape(user_input)})
  1. SQL注入防护:
# Django ORM自动防护 Book.objects.filter(title__contains=request.GET.get('query')) # 原始SQL必须使用参数化 from django.db import connection with connection.cursor() as cursor: cursor.execute("SELECT * FROM myapp_book WHERE title = %s", [user_input])

9. 测试驱动开发

9.1 单元测试示例

from django.test import TestCase from django.urls import reverse from .models import Author class AuthorTests(TestCase): @classmethod def setUpTestData(cls): Author.objects.create(name='Test Author', email='author@example.com') def test_author_listing(self): author = Author.objects.get(id=1) self.assertEqual(author.name, 'Test Author') self.assertEqual(author.email, 'author@example.com') def test_author_list_view(self): response = self.client.get(reverse('author-list')) self.assertEqual(response.status_code, 200) self.assertContains(response, 'Test Author') self.assertTemplateUsed(response, 'author/list.html')

9.2 API测试

from rest_framework.test import APITestCase from rest_framework import status class BookAPITests(APITestCase): def test_create_book(self): author = Author.objects.create(name='API Author') data = { 'title': 'Django Book', 'author': author.id, 'price': '99.99', 'stock': 10 } response = self.client.post('/api/books/', data) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(response.data['title'], 'Django Book')

10. 常见问题解决方案

  1. 静态文件404问题:
  • 确保DEBUG=False时运行了collectstatic
  • 检查Nginx/Apache配置的静态文件路径
  • 验证STATIC_ROOT和STATIC_URL设置
  1. 数据库连接问题:
# PostgreSQL配置示例 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'mydatabase', 'USER': 'mydatabaseuser', 'PASSWORD': 'mypassword', 'HOST': '127.0.0.1', 'PORT': '5432', } }
  1. 时区设置:
TIME_ZONE = 'Asia/Shanghai' USE_TZ = True # 建议启用时区支持
  1. 性能分析工具:
pip install django-debug-toolbar

配置settings.py:

INSTALLED_APPS += ['debug_toolbar'] MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware'] INTERNAL_IPS = ['127.0.0.1']

在开发过程中,我特别推荐使用django-extensions和ipython组合:

pip install django-extensions ipython python manage.py shell_plus --ipython

这个增强的shell会自动导入所有模型,极大提升开发效率。对于复杂查询调试,可以使用:

from django.db import connection print(connection.queries) # 查看已执行的SQL语句

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询