Python后端 -- 万字长文全面解析Django框架
自从2005年诞生以来,Django因其“开发速度快、安全性高”的特点迅速成为许多开发者的首选。无论是小型的个人项目,还是大型的企业应用,Django都能游刃有余地满足需求。我们将从Django的基础知识带你全面掌握Django,从基础知识到高级特性,让你在项目开发中得心应手。
目录
2. 函数视图(Function-Based Views, FBV)
3. 类视图(Class-Based Views, CBV)
Django简介与安装
1. Django是什么?
Django是一款开源的Web框架,基于Python语言开发,旨在帮助开发者快速构建高质量的Web应用程序。它采用了MVT(Model-View-Template)设计模式,与经典的MVC模式类似但更加灵活。Django的宗旨是“Don't Repeat Yourself”(别重复造轮子),通过封装常见的Web开发任务,减少开发者的工作量。
Django适合的场景
- 内容管理系统(CMS)
- 电商网站
- REST API后端
- 数据驱动的动态网站
2. Django的特点
- 快速开发: 提供大量开箱即用的功能模块,如用户认证、管理后台、ORM等。
- 安全性高: 内置常见的安全机制,防止SQL注入、跨站脚本(XSS)和跨站请求伪造(CSRF)。
- 可扩展性强: 丰富的插件生态系统,支持自定义开发。
- 强大的社区支持: 丰富的文档和活跃的开发者社区。
3. 环境搭建
在开始学习Django之前,需要准备开发环境,包括Python解释器和Django框架本身。
步骤一:检查或安装Python
# 检查是否已安装Python
python --version
如果未安装,前往Python官网下载最新版本并安装。
步骤二:创建虚拟环境
为避免依赖冲突,推荐在虚拟环境中安装Django:
python -m venv myenv
source myenv/bin/activate # macOS/Linux
myenv\Scripts\activate # Windows
步骤三:安装Django
使用pip
安装Django:
pip install django
#检查
django-admin --version
4. 创建第一个Django项目
创建一个新项目
django-admin startproject myproject
cd myproject
项目目录结构如下:
myproject/
manage.py
myproject/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
启动开发服务器
python manage.py runserver
#打开浏览器访问http://127.0.0.1:8000/,可以看到默认的欢迎页面。
Django项目结构解析
在上一部分,我们成功安装了Django,并创建了第一个Django项目。接下来,我们将深入了解Django项目的结构,搞清楚每个文件和目录的作用,从而为后续的开发工作奠定扎实的基础。
1. 项目与应用的区别
Django中的“项目”和“应用”是两个核心概念,理解它们的区别对项目组织非常重要。
- 项目(Project): 一个Django项目是一个整体的Web服务或网站,包含一系列设置和配置文件,用于定义网站的全局行为。
- 应用(App): 应用是项目中的一个子模块,负责实现某一特定功能,例如博客、论坛、用户管理等。一个项目可以包含多个应用。
类比示例:
将项目比作一本书,书中每一章就是一个应用。项目定义了书的标题、封面和大纲,而应用则实现了具体的内容。
2. Django项目目录结构
创建项目时生成的默认目录结构如下:
myproject/
manage.py
myproject/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
manage.py
一个命令行工具,用于与Django项目进行交互。例如启动服务器、执行数据库迁移等。
python manage.py runserver # 启动开发服务器
python manage.py makemigrations # 创建数据库迁移文件
python manage.py migrate # 应用数据库迁移
python manage.py createsuperuser # 创建管理员账号
__init__.py
一个空文件,表明该目录是一个Python包。
settings.py
全局配置文件,包括数据库设置、已安装的应用、静态文件路径等。
INSTALLED_APPS = [ # 已安装的应用
'django.contrib.admin',
'django.contrib.auth',
...
]
DATABASES = { # 数据库配置
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
urls.py
全局URL配置文件,用于定义项目的路由规则。
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
]
asgi.py
异步服务器网关接口配置,用于支持异步请求处理。
wsgi.py
Web服务器网关接口配置,用于生产环境部署。
3. Django应用的基本构造
在Django中,应用是实现具体功能的基本单位。我们可以通过以下命令创建一个应用:
python manage.py startapp myapp
生成的应用目录结构如下:
myapp/
admin.py
apps.py
models.py
tests.py
views.py
migrations/
__init__.py
admin.py
配置Django管理后台中的数据展示。
from django.contrib import admin
from .models import MyModel
admin.site.register(MyModel)
apps.py
配置应用的元信息。
models.py
定义数据库模型。
tests.py
用于编写单元测试。
views.py
定义视图逻辑,用于处理用户请求并返回响应。
migrations/
用于存储数据库迁移文件。
4. 注册应用
在创建应用后,需将其注册到项目中,使Django识别该应用。步骤如下:
- 打开
settings.py
文件。 - 在
INSTALLED_APPS
中添加应用名称:
INSTALLED_APPS = [
...
'myapp',
]
5. Django中的重要文件总结
Django项目和应用中的核心文件共同构成了项目的开发框架:
settings.py
: 全局配置中心。urls.py
: 路由管理。models.py
: 数据库模型设计。views.py
: 处理请求并返回响应。admin.py
: 管理后台配置。
Django模型层(Models)
Django模型(Models)是框架的重要组成部分,用于处理与数据库的交互。通过Django的ORM(Object-Relational Mapping,对象关系映射),开发者可以直接使用Python代码操作数据库,而无需编写繁琐的SQL语句。本部分将从模型的定义、关系设计到数据库操作,带你全面了解Django的模型层。
1. ORM概述
Django的ORM是一种将Python对象与数据库表对应起来的技术。通过ORM,开发者可以:
- 定义数据库表结构。
- 使用Python代码进行增删改查操作。
- 轻松切换数据库(如SQLite、PostgreSQL、MySQL)。
优点
- 简化了数据库操作的复杂度。
- 提高了代码的可读性和可维护性。
- 提供了一致的API接口,支持多种数据库。
2. 模型的定义
在Django中,模型是Python类,每个类对应一个数据库表,类中的属性对应表中的字段。
基本模型定义
创建一个名为models.py
的文件,并定义模型:
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100) # 字符串字段
email = models.EmailField() # 邮箱字段
bio = models.TextField(blank=True, null=True) # 可选字段
def __str__(self):
return self.name
字段类型
Django提供了多种字段类型,常用字段包括:
- CharField: 用于存储短文本,需指定
max_length
。 - TextField: 用于存储长文本。
- IntegerField: 存储整数。
- FloatField: 存储浮点数。
- DateField/DateTimeField: 存储日期或日期时间。
- BooleanField: 存储布尔值。
- EmailField: 用于存储并验证邮箱格式。
- FileField/ImageField: 用于存储文件或图片。
字段选项
字段支持多个选项,用于控制数据库行为:
null=True
: 数据库中该字段可以为空。blank=True
: 表单中该字段可以为空。default=value
: 设置字段的默认值。choices=
: 定义字段的枚举值。
class Book(models.Model):
GENRE_CHOICES = [
('FIC', 'Fiction'),
('NF', 'Non-Fiction'),
('SF', 'Science Fiction'),
]
title = models.CharField(max_length=200)
genre = models.CharField(max_length=3, choices=GENRE_CHOICES)
published_date = models.DateField()
3. 模型的关系
Django支持一对一、一对多和多对多关系。
一对一关系
使用OneToOneField
定义一对一关系:
class Profile(models.Model):
user = models.OneToOneField('auth.User', on_delete=models.CASCADE)
bio = models.TextField()
一对多关系
使用ForeignKey
定义一对多关系:
class Article(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
多对多关系
使用ManyToManyField
定义多对多关系:
class Student(models.Model):
name = models.CharField(max_length=100)
class Course(models.Model):
name = models.CharField(max_length=100)
students = models.ManyToManyField(Student)
4. 迁移与数据库操作
定义模型后,需要将其同步到数据库中。Django提供了迁移工具来完成这一任务。
创建迁移文件
运行以下命令生成迁移文件:
python manage.py makemigrations
生成的迁移文件描述了数据库的变更。
应用迁移
运行以下命令将迁移应用到数据库:
python manage.py migrate
5. 数据库操作
Django提供了对模型的增删改查操作的API。
创建记录
author = Author(name="John Doe", email="john@example.com")
author.save()
查询所有记录
Author.objects.all()
条件查询:
Author.objects.filter(name="John Doe")
获取单个对象:
Author.objects.get(id=1)
更新记录
author = Author.objects.get(id=1)
author.email = "new_email@example.com"
author.save()
删除记录
author = Author.objects.get(id=1)
author.delete()
排序:
Author.objects.order_by('name')
分页:
Author.objects.all()[:10]
6. 模型管理器(Manager)
Django的objects
是模型的默认管理器,可以通过自定义管理器扩展其功能:
class AuthorManager(models.Manager):
def active_authors(self):
return self.filter(is_active=True)
class Author(models.Model):
name = models.CharField(max_length=100)
is_active = models.BooleanField(default=True)
objects = AuthorManager()
#调用自定义方法
active_authors = Author.objects.active_authors()
Django视图层(Views)
在Django中,视图(Views)是处理用户请求并返回响应的核心部分。通过视图,我们可以定义应用的业务逻辑,将模型数据传递给模板,最终生成动态的网页内容。本部分将详细讲解视图的基本概念、类型及其在项目中的实际应用。
1. 视图的基本概念
Django视图是一个Python函数或类,接收HTTP请求对象(HttpRequest
),处理逻辑后返回HTTP响应对象(HttpResponse
)。
视图的职责
- 处理用户请求。
- 执行业务逻辑(如查询数据库)。
- 渲染模板并返回响应。
2. 函数视图(Function-Based Views, FBV)
Django的函数视图是最基本的视图形式,定义为普通的Python函数。
示例:简单的函数视图
from django.http import HttpResponse
def hello_world(request):
return HttpResponse("Hello, World!")
视图绑定URL
在urls.py
中绑定视图函数到特定的URL:
from django.urls import path
from . import views
urlpatterns = [
path('hello/', views.hello_world),
]
访问http://127.0.0.1:8000/hello/
时,将返回Hello, World!
。
视图中的逻辑处理
视图可以包含复杂的逻辑,例如查询数据库并动态生成响应:
from django.shortcuts import render
from .models import Article
def article_list(request):
articles = Article.objects.all()
return render(request, 'articles.html', {'articles': articles})
render
:用于渲染模板。'articles.html'
:模板文件的名称。{'articles': articles}
:上下文数据传递给模板。
3. 类视图(Class-Based Views, CBV)
Django提供了类视图,便于处理复杂的逻辑。类视图将请求处理拆分为多个方法,增强了代码的可复用性。
基本类视图
定义一个简单的类视图:
from django.http import HttpResponse
from django.views import View
class HelloWorldView(View):
def get(self, request):
return HttpResponse("Hello, World from Class-Based View!")
绑定URL
from django.urls import path
from .views import HelloWorldView
urlpatterns = [
path('hello/', HelloWorldView.as_view()),
]
通用类视图(Generic Views)
Django内置了一些通用类视图,用于处理常见任务,如显示列表或详细信息。
- ListView: 显示对象列表。
-
DetailView: 显示单个对象的详细信息。
from django.views.generic import ListView
from .models import Article
class ArticleListView(ListView):
model = Article
template_name = 'articles.html'
context_object_name = 'articles'
绑定URL
urlpatterns = [
path('articles/', ArticleListView.as_view(), name='article_list'),
]
4. 视图中的请求与响应
视图需要处理用户的请求,并生成适当的响应。
HttpRequest对象
request
对象包含了与用户请求相关的所有信息:
request.method
: 请求方法(GET、POST等)。request.GET
: 获取查询参数。request.POST
: 获取表单提交数据。
示例:
def search(request):
query = request.GET.get('q')
return HttpResponse(f"Search query: {query}")
HttpResponse对象
HttpResponse
用于返回自定义的响应:
HttpResponse(content)
: 返回纯文本内容。HttpResponseRedirect(url)
: 重定向到指定URL。JsonResponse(data)
: 返回JSON数据。
5. 视图与模板结合
通常,视图通过模板引擎生成动态网页。
使用render
渲染模板
render
函数简化了模板渲染的过程:
from django.shortcuts import render
def home(request):
context = {'title': 'Welcome to Django'}
return render(request, 'home.html', context)
在模板中使用上下文数据
模板文件home.html
示例:
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}</h1>
</body>
</html>
6. 处理错误和异常
Django视图可以通过内置方法处理错误或异常,提供更友好的用户体验。
自定义404页面 是的404!
在views.py
中定义404视图:
from django.http import HttpResponseNotFound
def custom_404_view(request, exception):
return HttpResponseNotFound("Page not found!")
# 在settings.py中配置:
handler404 = 'myapp.views.custom_404_view'
7. 中间件与视图
中间件可以在请求到达视图之前或响应返回用户之前,处理一些通用任务。例如,认证、日志记录等。
示例:记录请求路径的中间件:
class LogMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
print(f"Request path: {request.path}")
return self.get_response(request)
在settings.py
中注册:
MIDDLEWARE = [
...,
'myapp.middleware.LogMiddleware',
]
Django模板层(Templates)
Django模板层(Templates)负责将动态数据渲染为HTML页面,向用户呈现最终的内容。模板系统采用一种简洁的语法,让开发者专注于页面结构,而将复杂的逻辑留在视图层。本部分将详细介绍Django模板语言的语法、模板继承机制以及静态文件的管理。
1. 模板语言语法
Django模板语言(Django Template Language,DTL)是一种简洁的标记语言,用于动态渲染HTML内容。其语法由变量、标签和过滤器组成。
1.1 变量
模板中的变量使用双花括号包裹:
<p>{{ variable_name }}</p>
标签是控制模板逻辑的核心,使用{% ... %}
表示。常见标签包括:
- **
{% if %}
:条件语句。 - **
{% for %}
:循环语句。 - **
{% include %}
:包含其他模板。
示例:
{% if user_name %}
<p>Hello, {{ user_name }}!</p>
{% else %}
<p>Hello, Guest!</p>
{% endif %}
过滤器用于格式化变量,语法为{{ variable|filter_name }}
。 常见过滤器:
date
:格式化日期。lower
:将字符串转为小写。length
:获取列表长度。
示例:
<p>{{ current_date|date:"Y-m-d" }}</p>
<p>{{ user_name|lower }}</p>
2. 模板的使用
模板文件通常存放在项目的templates
目录下,需在settings.py
中配置模板路径:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'], # 自定义模板目录
'APP_DIRS': True,
...
},
]
创建模板文件: 项目目录结构:
myproject/
templates/
home.html
渲染模板: 在视图中调用render
:
def home(request):
return render(request, 'home.html', {'title': 'Welcome to Django'})
模板内容:
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}</h1>
</body>
</html>
3. 模板继承与模块化
模板继承机制允许定义通用的页面结构,并通过子模板进行扩展,从而减少重复代码。
3.1 定义父模板
父模板通常定义页面的通用结构:
<!-- templates/base.html -->
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}My Site{% endblock %}</title>
</head>
<body>
<header>
<h1>My Website Header</h1>
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>
<p>My Website Footer</p>
</footer>
</body>
</html>
3.2 定义子模板
子模板继承父模板,并重写指定的块内容:
<!-- templates/home.html -->
{% extends 'base.html' %}
{% block title %}Home Page{% endblock %}
{% block content %}
<p>Welcome to the home page!</p>
{% endblock %}
3.3 使用模板继承的页面渲染
视图调用子模板:
def home(request):
return render(request, 'home.html')
4. 模板中的静态文件
静态文件(CSS、JavaScript、图片等)用于增强页面的视觉和交互效果。Django提供了一套机制来管理静态文件。
配置静态文件
在settings.py
中配置静态文件路径:
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / 'static']
# 确保在模板文件中加载静态文件标签:
{% load static %}
# 引用静态文件:
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
<img src="{% static 'images/logo.png' %}" alt="Logo">
5. 模板的自定义标签和过滤器
当Django内置的标签和过滤器无法满足需求时,可以自定义。
# 在应用目录下创建一个templatetags目录,添加自定义过滤
# myapp/templatetags/custom_filters.py
from django import template
register = template.Library()
@register.filter
def add_prefix(value, prefix):
return f"{prefix}{value}"
# 在模板中加载并使用:
{% load custom_filters %}
<p>{{ 'World'|add_prefix:'Hello, ' }}</p>
Django URL解析
在一个Web应用中,URL是用户与应用交互的入口。Django通过URL解析将用户请求与视图关联起来,并根据URL模式决定调用哪个视图处理请求。本部分将深入讲解Django的URL解析机制、动态URL配置以及命名空间和反向解析的使用。
1. URL配置的基础
Django通过urls.py
文件将URL模式映射到视图。
# 项目的urls.py文件
from django.contrib import admin
from django.urls import path
from myapp import views # 引入应用视图
# 定义URL模式列表
urlpatterns = [
path('admin/', admin.site.urls), # 管理后台
path('home/', views.home, name='home'), # 静态路径绑定到视图
]
# 示例视图:返回简单的响应
# myapp/views.py
from django.http import HttpResponse
def home(request):
return HttpResponse("Welcome to the Home Page!")
访问路径 /home/
将调用 home
视图,返回 "Welcome to the Home Page!"。
2. 动态URL
动态URL允许捕获路径参数并传递到视图中。
# 定义动态URL
urlpatterns = [
path('article/<int:article_id>/', views.article_detail, name='article_detail'),
]
# 视图函数处理动态参数
def article_detail(request, article_id):
return HttpResponse(f"Article ID: {article_id}")
- 访问
/article/42/
,将显示Article ID: 42
。 <int:article_id>
捕获整数类型的路径参数。
支持的动态参数类型:
<str>
:字符串(默认)。<int>
:整数。<slug>
:短字符串。<path>
:带斜杠的字符串。<uuid>
:UUID格式。
3. 命名空间与反向解析
为提高可维护性,可以为URL模式命名,并通过反向解析动态生成URL。
# 定义带名称的URL
urlpatterns = [
path('home/', views.home, name='home'), # 给URL模式命名为 'home'
]
# 视图中使用反向解析生成URL
from django.urls import reverse
def redirect_to_home(request):
home_url = reverse('home') # 根据名称动态生成URL
return HttpResponse(f"The URL for 'home' is: {home_url}")
# 模板中反向解析URL
# home.html
<a href="{% url 'home' %}">Go to Home</a>
reverse('home')
返回/home/
。- 模板中的
{% url 'home' %}
动态生成链接。
4. 命名空间
在大型项目中,可以为每个应用的URL配置添加命名空间。
# 应用的urls.py文件
from django.urls import path
app_name = 'myapp' # 定义命名空间
urlpatterns = [
path('home/', views.home, name='home'), # 定义命名URL
]
# 主urls.py文件
from django.urls import include
urlpatterns = [
path('myapp/', include('myapp.urls')), # 引入应用URL
]
# 模板中使用命名空间的反向解析
<a href="{% url 'myapp:home' %}">Go to MyApp Home</a>
使用 myapp:home
指定命名空间和URL名称,避免冲突。
5. 正则表达式URL
对于复杂的路径需求,可以使用re_path
结合正则表达式定义URL。
from django.urls import re_path
# 定义正则表达式URL模式
urlpatterns = [
re_path(r'^article/(?P<year>\d{4})/$', views.article_by_year, name='article_by_year'),
]
# 视图中接收正则表达式参数
def article_by_year(request, year):
return HttpResponse(f"Articles from year: {year}")
- URL
/article/2024/
将返回Articles from year: 2024
。 (?P<year>\d{4})
捕获名为year
的四位数字参数。
6. URL优化
Django提供了工具和技巧优化URL设计:
-
使用
include
组织URL: 将每个应用的URL配置拆分到独立文件中。
# 主urls.py
from django.urls import include
urlpatterns = [
path('blog/', include('blog.urls')), # 引入博客应用URL配置
]
- 规范设计URL: 避免嵌套过深的路径,遵循RESTful设计原则,例如:
/users/
:用户列表。/users/<id>/
:单个用户详情。
从初识Django,到逐步掌握模型、视图、模板,再到URL解析,如果你问我,Django最大的魅力是什么,我会说它的“有条不紊”。从后台逻辑到前端显示,从简单的Hello World到复杂的数据库查询,Django用一种条理清晰的方式让我们既能快速上手,又能应对复杂场景。就像一个好用的工具箱,拿出来就是各种好用的工具,一切都那么顺理成章。
你可能已经开始计划用Django做点什么了。是一个简单的博客,还是一个功能复杂的电商网站?无论如何,Django的学习远不止于此。它还有更多的高级特性等待你去探索,Enjoy coding,and keep building!
原文地址:https://blog.csdn.net/qq_52213943/article/details/144267758
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!