Django 教程入门指南 – wiki基地


Django 入门指南:从零开始构建你的第一个 Web 应用

欢迎来到 Django 的世界!Django 是一个高级 Python Web 框架,鼓励快速开发和干净、实用的设计。它由经验丰富的开发人员构建,解决了 Web 开发中许多令人头疼的问题,因此你可以专注于编写应用程序,而无需重新发明轮子。它免费且开源。

本指南旨在为初学者提供一个全面而详细的 Django 入门路径。我们将从基础概念讲起,逐步搭建环境、创建项目、理解核心组件,并最终构建一个简单的 Web 应用。本文篇幅较长,内容详尽,希望能助你稳固地踏出 Django 开发的第一步。

阅读本文前,你应该具备:

  1. 基本的 Python 知识: 了解 Python 语法、数据类型、函数、类等。
  2. 命令行/终端基础: 熟悉基本的命令行操作(cd, ls/dir, mkdir等)。
  3. 基本的 Web 概念: 对 HTTP 请求/响应、HTML、CSS 有初步了解。

本文将涵盖:

  1. 什么是 Django?为什么选择它?
  2. 环境搭建: 安装 Python、pip、虚拟环境和 Django。
  3. 创建你的第一个 Django 项目: 项目结构解析。
  4. 创建你的第一个 Django 应用: 理解项目与应用的关系。
  5. Django 核心概念: 请求/响应周期、URL 路由、视图(Views)、模板(Templates)。
  6. 数据库与模型(Models): 定义数据结构、数据库迁移。
  7. 强大的 Django Admin 后台。
  8. 处理静态文件(CSS, JavaScript, 图片)。
  9. 处理表单(Forms)。
  10. 后续学习建议。

1. 什么是 Django?为什么选择它?

Django 诞生于一个快节奏的新闻编辑室环境,旨在满足新闻机构网站开发的苛刻期限和要求。它遵循 MVT(Model-View-Template) 架构模式,这与常见的 MVC(Model-View-Controller)模式略有不同,但目标相似:分离关注点,使代码更易于维护和扩展。

  • Model(模型): 数据访问层。负责处理应用程序的数据结构,并与数据库进行交互。Django 提供了一个强大的对象关系映射器(ORM),让你用 Python 代码来定义和操作数据库表。
  • View(视图): 业务逻辑层。接收 HTTP 请求,执行必要的逻辑(可能涉及与模型的交互),并返回一个 HTTP 响应。在 Django 中,视图通常是一个 Python 函数或类。
  • Template(模板): 表现层。负责生成用户看到的 HTML。Django 拥有自己强大而灵活的模板语言,可以方便地将动态数据嵌入到 HTML 结构中。

选择 Django 的理由:

  • 功能完备(Batteries Included): Django 自带了大量常用功能模块,如用户认证、管理后台、表单处理、站点地图、RSS feeds 等,开箱即用,大大减少了开发时间和工作量。
  • 强大的 ORM: 无需编写复杂的 SQL 语句(尽管也可以),通过 Python 类即可定义数据库模型并进行增删改查操作,支持多种数据库后端(PostgreSQL, MySQL, SQLite, Oracle)。
  • 自动化的管理后台: Django 最受欢迎的功能之一。只需几行代码,就能为你的数据模型生成一个功能齐全、可定制的管理界面,方便内容管理。
  • 安全性: Django 内置了多种安全防护机制,帮助开发者避免常见的 Web 安全漏洞,如跨站脚本(XSS)、跨站请求伪造(CSRF)、SQL 注入等。
  • 可扩展性: Django 的组件化设计使其易于扩展。你可以轻松地集成第三方应用,或者将自己的应用设计成可重用的模块。
  • 成熟且活跃的社区: 拥有庞大且活跃的开发者社区,文档齐全,遇到问题时很容易找到解决方案和支持。
  • 遵循设计哲学:
    • DRY (Don’t Repeat Yourself): 避免代码冗余。
    • Convention over Configuration: 遵循约定可以减少配置的复杂性。
    • Explicit is better than implicit: 代码应清晰易懂。

2. 环境搭建

在开始 Django 开发之前,我们需要确保本地开发环境已经准备就绪。

2.1 安装 Python

Django 是一个 Python 框架,因此首先需要安装 Python。访问 Python 官方网站 python.org 下载适合你操作系统的最新稳定版本(推荐 Python 3.8 或更高版本)。

安装时,请确保勾选 “Add Python to PATH”(Windows)或类似选项,以便在命令行中直接使用 python 命令。

安装完成后,打开命令行/终端,输入以下命令验证安装:

“`bash
python –version

或者 python3 –version (取决于你的系统和安装方式)

“`

你应该能看到安装的 Python 版本号。

2.2 安装 pip

pip 是 Python 的包管理器,用于安装和管理 Python 库。现代 Python 版本通常自带 pip。验证 pip 是否可用:

“`bash
pip –version

或者 pip3 –version

“`

如果提示找不到命令,你可能需要单独安装 pip 或修复 Python 的 PATH 配置。通常,重新安装 Python 并确保勾选添加到 PATH 的选项可以解决问题。

2.3 使用虚拟环境(强烈推荐)

为每个 Django 项目创建一个独立的虚拟环境是一个非常好的实践。虚拟环境可以隔离项目依赖,避免不同项目之间的库版本冲突。

  • 创建虚拟环境:
    打开命令行,进入你打算存放项目的目录,然后运行:

    “`bash

    创建一个名为 ‘venv’ 的虚拟环境目录

    python -m venv venv

    或者 python3 -m venv venv

    “`

  • 激活虚拟环境:

    • Windows:
      bash
      venv\Scripts\activate

      激活后,命令行提示符前通常会显示 (venv)
    • macOS / Linux:
      bash
      source venv/bin/activate

      激活后,命令行提示符前通常会显示 (venv)
  • 退出虚拟环境:
    在激活的虚拟环境中,运行:
    bash
    deactivate

重要: 之后的所有 pip installpython 命令都应在激活的虚拟环境中执行。

2.4 安装 Django

确保你的虚拟环境已激活。然后使用 pip 安装 Django:

bash
pip install django

pip 会自动下载并安装最新稳定版的 Django 及其依赖项。

验证 Django 是否安装成功:

bash
django-admin --version

你应该能看到安装的 Django 版本号。


3. 创建你的第一个 Django 项目

一个 Django 项目(Project) 是一个 Django 实例的配置和应用的集合。可以把它看作是整个网站的容器。

激活的虚拟环境中,使用 django-admin 命令创建一个新项目。我们将项目命名为 mysite。进入你希望创建项目的目录,然后运行:

“`bash

注意末尾的 ‘.’ 表示在当前目录下创建项目文件

如果省略 ‘.’,它会在当前目录下创建一个名为 mysite 的新目录,并将项目文件放在里面

django-admin startproject mysite .
“`

执行后,当前目录下会生成以下文件和目录结构:

.
├── manage.py # 一个命令行工具,用于与 Django 项目进行各种交互
└── mysite/ # 项目的 Python 包(与项目同名)
├── __init__.py # 一个空文件,告诉 Python 这个目录应该被视为一个 Python 包
├── asgi.py # 用于 ASGI 兼容的 Web 服务器的入口点 (用于异步)
├── settings.py # 项目的配置文件
├── urls.py # 项目的 URL 声明(路由配置)
├── wsgi.py # 用于 WSGI 兼容的 Web 服务器的入口点 (用于同步)

  • manage.py 非常重要的工具。你将通过它执行各种 Django 命令,如启动开发服务器、创建数据库迁移、运行测试等。
  • mysite/ (内层目录): 这是你的项目的实际 Python 包。它的名字会被用在 Python 导入中(例如 import mysite.settings)。
  • __init__.py 表明 mysite/ 是一个 Python 包。
  • settings.py 包含了项目的所有配置,如数据库设置、应用列表、模板路径、静态文件路径、中间件、时区等。这是你需要经常编辑的文件。
  • urls.py 定义了项目的 URL 路由规则。它将 URL 路径映射到相应的视图函数或类。
  • asgi.py / wsgi.py 用于部署到生产环境时与 Web 服务器(如 Nginx + Gunicorn/Uvicorn)的接口文件。

运行开发服务器

Django 自带一个轻量级的 Web 服务器,方便开发和测试。在包含 manage.py 的目录下(即项目根目录),运行:

bash
python manage.py runserver

你会看到类似以下的输出:

“`
Watching for file changes with StatReloader
Performing system checks…

System check identified no issues (0 silenced).
November 16, 2023 – 10:30:00
Django version 4.2.7, using settings ‘mysite.settings’
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK (Windows) or CTRL-C (macOS/Linux).
“`

现在,打开你的 Web 浏览器,访问 http://127.0.0.1:8000/http://localhost:8000/。你应该能看到 Django 的默认欢迎页面,表示项目已成功创建并运行。

CTRL+C 可以停止开发服务器。


4. 创建你的第一个 Django 应用

在 Django 中,一个应用(App) 是一个实现特定功能的 Web 应用程序模块。例如,一个博客网站可能包含文章(post)、评论(comment)、用户(user)等应用。项目是应用的集合和配置。良好的实践是将网站功能拆分成多个可重用的应用。

让我们创建一个名为 polls 的应用,用于处理简单的投票功能。确保你在项目根目录(包含 manage.py 的地方)并且虚拟环境已激活。运行:

bash
python manage.py startapp polls

这会在项目根目录下创建一个名为 polls 的新目录,包含以下文件:

polls/
├── __init__.py
├── admin.py # 配置此应用在 Django Admin 后台的显示
├── apps.py # 此应用的配置信息
├── migrations/ # 存放数据库迁移文件
│ └── __init__.py
├── models.py # 定义此应用的数据模型 (数据库表结构)
├── tests.py # 编写此应用的单元测试
└── views.py # 定义此应用的视图 (处理请求和响应)

注册应用

创建应用后,你需要告诉 Django 项目它的存在。打开项目配置文件 mysite/settings.py,找到 INSTALLED_APPS 列表,并将你的新应用添加进去。通常建议添加应用的配置类(在 apps.py 中定义),格式为 'app_name.apps.AppNameConfig'

“`python

mysite/settings.py

INSTALLED_APPS = [
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘polls.apps.PollsConfig’, # 添加这一行
# 或者直接写应用名 ‘polls’,Django 也能识别,但推荐用 Config 类
]
“`

现在 Django 知道 polls 应用了。


5. Django 核心概念:请求/响应、URL、视图、模板

让我们来实践 Django 处理 Web 请求的核心流程。我们将创建一个简单的视图,并通过 URL 访问它。

5.1 请求/响应周期回顾

  1. 用户在浏览器输入 URL。
  2. 浏览器向服务器发送 HTTP 请求。
  3. Web 服务器(开发服务器或生产服务器)接收请求,并将其传递给 Django。
  4. Django 的 URL 路由系统(URL dispatcher)根据 urls.py 中的配置,查找与请求 URL 匹配的模式。
  5. 如果找到匹配项,URL 路由系统调用对应的视图函数或类方法。
  6. 视图函数处理请求,可能执行数据库查询(通过模型)、加载模板等操作。
  7. 视图函数返回一个 HTTP 响应(通常是渲染后的 HTML 页面,或重定向、JSON 数据等)。
  8. Django 将响应发送回 Web 服务器。
  9. Web 服务器将响应发送回浏览器。
  10. 浏览器渲染收到的响应(例如显示 HTML 页面)。

5.2 创建第一个视图 (View)

视图是处理 Web 请求并返回响应的 Python 函数或类。打开 polls/views.py 文件,编写一个简单的视图函数:

“`python

polls/views.py

from django.http import HttpResponse

def index(request):
# request 参数是一个 HttpRequest 对象,包含了请求的所有信息
# 这个简单的视图直接返回一个包含文本的 HTTP 响应
return HttpResponse(“Hello, world. You’re at the polls index.”)
“`

5.3 配置 URL 路由

我们需要将一个 URL 路径映射到刚刚创建的 index 视图。Django 的 URL 配置是分层的:项目有一个主 urls.py,每个应用可以有自己的 urls.py

  • 创建应用的 urls.py
    polls 目录下创建一个新文件 urls.py

    “`python

    polls/urls.py

    from django.urls import path
    from . import views # 从当前目录导入 views 模块

    定义这个应用的 URL 模式列表

    Django 建议为应用 URL 模式添加命名空间,以便在模板或代码中引用

    app_name = ‘polls’
    urlpatterns = [
    # 当访问 polls/ (即应用的根路径) 时,调用 views.py 中的 index 函数
    path(”, views.index, name=’index’),
    # 第一个参数是 URL 模式 (空字符串表示应用的根)
    # 第二个参数是匹配成功后调用的视图函数
    # 第三个参数 ‘name’ 是这个 URL 模式的唯一名称,方便反向解析
    ]
    “`

  • 将应用的 URL 配置包含到项目中:
    打开项目的主 urls.py 文件 (mysite/urls.py),修改它以包含 polls 应用的 URL 配置。我们需要使用 include 函数。

    “`python

    mysite/urls.py

    from django.contrib import admin
    from django.urls import path, include # 导入 include 函数

    urlpatterns = [
    path(‘admin/’, admin.site.urls),
    # 当 URL 以 ‘polls/’ 开头时,
    # 将 URL 的剩余部分交给 polls.urls 模块处理
    path(‘polls/’, include(‘polls.urls’)),
    ]
    “`

现在,访问 http://localhost:8000/polls/ 的请求会被路由到 polls 应用的 urls.py,进而匹配空字符串 '' 模式,最终调用 polls.views.index 函数。

测试:
确保开发服务器正在运行 (python manage.py runserver)。在浏览器中访问 http://127.0.0.1:8000/polls/。你应该能看到 “Hello, world. You’re at the polls index.”。

5.4 使用模板 (Templates)

直接在视图中返回硬编码的 HTML 是不灵活的。我们需要使用模板来分离表现逻辑。

  • 创建模板目录:
    polls 应用目录下创建一个名为 templates 的子目录,然后在 templates 目录下再创建一个与应用同名的子目录 polls。这是 Django 默认查找应用模板的约定路径 (app_name/templates/app_name/)。
    polls/
    ├── templates/
    │ └── polls/
    │ └── index.html <-- 在这里创建模板文件
    ├── __init__.py
    ├── admin.py
    ...
    └── views.py

  • 创建模板文件:
    polls/templates/polls/ 目录下创建 index.html 文件:

    “`html

    <!DOCTYPE html>


    Polls Index

    {{ question_text }}

    {% if latest_question_list %} <!-- 使用花括号百分号进行逻辑控制 -->
        <ul>
        {% for question in latest_question_list %}
            <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
        {% endfor %}
        </ul>
    {% else %}
        <p>No polls are available.</p>
    {% endif %}
    



    ``
    这个模板使用了 Django 模板语言 (DTL):
    *
    {{ variable }}用于输出变量的值。
    *
    {% tag %}用于执行逻辑,如if判断、for` 循环等。

  • 修改视图以渲染模板:
    回到 polls/views.py,修改 index 视图,让它加载并渲染模板。我们需要使用 render快捷函数。

    “`python

    polls/views.py

    from django.shortcuts import render # 导入 render
    from django.http import HttpResponse

    假设我们后面会从数据库获取数据,这里先模拟一些数据

    from .models import Question # 稍后会用到

    def index(request):
    # 模拟从数据库获取的数据
    latest_question_list = [
    {‘id’: 1, ‘question_text’: ‘What is your favorite color?’},
    {‘id’: 2, ‘question_text’: ‘Which framework do you prefer?’},
    ]
    # 构建传递给模板的上下文数据(一个字典)
    context = {
    ‘latest_question_list’: latest_question_list,
    ‘question_text’: “List of Polls” # 示例变量
    }
    # 使用 render 函数加载模板并传递上下文
    # Django 会自动在应用的 templates 目录下查找 ‘polls/index.html’
    return render(request, ‘polls/index.html’, context)

    你可以保留之前的简单视图,或者创建新的视图函数

    def simple_hello(request):

    return HttpResponse(“Hello, world.”)

    ``
    确保你的
    polls/urls.py指向的是这个更新后的index` 视图。

测试:
刷新浏览器中的 http://127.0.0.1:8000/polls/ 页面。现在你应该看到一个由 HTML 模板渲染出来的页面,包含标题和我们模拟的问题列表。


6. 数据库与模型 (Models)

模型是数据的单一、权威的信息来源。它包含了存储数据的基本字段和行为。每个模型都映射到数据库中的一张表。

6.1 定义模型

打开 polls/models.py 文件,定义两个模型:Question(问题)和 Choice(选项)。

“`python

polls/models.py

import datetime
from django.db import models
from django.utils import timezone

class Question(models.Model):
# 问题文本,CharField 需要指定 max_length
question_text = models.CharField(max_length=200)
# 发布日期,DateTimeField
pub_date = models.DateTimeField(‘date published’)

def __str__(self):
    # 定义对象的字符串表示,方便在 admin 或 shell 中查看
    return self.question_text

def was_published_recently(self):
    # 自定义方法,判断问题是否是最近发布的
    now = timezone.now()
    return now - datetime.timedelta(days=1) <= self.pub_date <= now

class Choice(models.Model):
# 外键关联到 Question 模型,一个 Question 可以有多个 Choice
# on_delete=models.CASCADE 表示当关联的 Question 被删除时,这个 Choice 也一起删除
question = models.ForeignKey(Question, on_delete=models.CASCADE)
# 选项文本
choice_text = models.CharField(max_length=200)
# 票数,IntegerField,默认为 0
votes = models.IntegerField(default=0)

def __str__(self):
    return self.choice_text

“`

这里我们定义了两个模型类,它们都继承自 django.db.models.Model。每个类变量(如 question_text, pub_date)都是一个模型字段(Field)的实例,代表数据库表中的一列。Django 提供了多种字段类型(CharField, DateTimeField, IntegerField, ForeignKey 等)。

6.2 数据库迁移 (Migrations)

定义或修改模型后,你需要告诉 Django 如何将这些更改应用到数据库。这个过程叫做迁移(Migration)。

  • 生成迁移文件:
    在命令行(项目根目录,虚拟环境激活状态)运行:
    bash
    python manage.py makemigrations polls

    Django 会检测 polls/models.py 中的更改,并在 polls/migrations/ 目录下生成一个新的迁移文件(例如 0001_initial.py)。这个文件包含了将模型更改翻译成数据库操作(如 CREATE TABLE)的 Python 代码。

  • 应用迁移:
    运行以下命令将迁移应用到数据库(即执行迁移文件中的操作):
    bash
    python manage.py migrate

    Django 会查找所有 INSTALLED_APPS 中尚未应用的迁移,并根据 settings.py 中的数据库配置,在指定的数据库(默认为项目根目录下的 db.sqlite3 文件)中创建相应的表。

现在,你的数据库中已经有了 polls_questionpolls_choice 两张表。

6.3 使用 Django Shell 与模型交互

Django 提供了一个交互式 Python shell,可以方便地测试和操作模型。

bash
python manage.py shell

进入 shell 后,你可以导入模型并使用 Django ORM 进行数据库操作:

“`python

from polls.models import Question, Choice
from django.utils import timezone

创建一个 Question 对象

q = Question(question_text=”What’s new?”, pub_date=timezone.now())
q.save() # 保存到数据库

查询所有 Question

Question.objects.all()
]>

根据 ID 获取 Question

q = Question.objects.get(pk=1) # pk 是 primary key 的缩写
q.question_text
“What’s new?”

为 Question 添加 Choice

q.choice_set.create(choice_text=’Not much’, votes=0)

q.choice_set.create(choice_text=’The sky’, votes=0)

c = q.choice_set.create(choice_text=’Just hacking’, votes=0)

Choice 对象可以通过 question 属性访问关联的 Question

c.question

Question 对象可以通过 _set (如 choice_set) 访问关联的 Choice 集合

q.choice_set.all()
, \, \]>

过滤查询

Question.objects.filter(question_text__startswith=’What’)
]>

退出 shell

exit()
“`

6.4 在视图中使用模型

现在我们可以在视图中真正地从数据库获取数据了。修改 polls/views.pyindex 视图:

“`python

polls/views.py

from django.shortcuts import render
from .models import Question # 导入 Question 模型

def index(request):
# 获取数据库中按发布日期降序排列的最新 5 个问题
latest_question_list = Question.objects.order_by(‘-pub_date’)[:5]
context = {‘latest_question_list’: latest_question_list}
return render(request, ‘polls/index.html’, context)

我们可以添加更多视图,例如显示问题详情和选项

from django.http import Http404
from django.shortcuts import get_object_or_404

def detail(request, question_id):
# 尝试获取指定 ID 的 Question,如果不存在则抛出 404 错误
question = get_object_or_404(Question, pk=question_id)
# 渲染详情页模板 (需要创建 polls/detail.html)
return render(request, ‘polls/detail.html’, {‘question’: question})

def results(request, question_id):
question = get_object_or_404(Question, pk=question_id)
# 渲染结果页模板 (需要创建 polls/results.html)
return render(request, ‘polls/results.html’, {‘question’: question})

处理投票的视图 (后面会结合表单)

from django.http import HttpResponseRedirect
from django.urls import reverse

def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
# request.POST 是一个类字典对象,包含 POST 请求的数据
# 这里尝试获取名为 ‘choice’ 的数据,值是 choice 的 ID
selected_choice = question.choice_set.get(pk=request.POST[‘choice’])
except (KeyError, Choice.DoesNotExist):
# 如果 ‘choice’ 不存在或 ID 无效,重新显示问题详情页并带上错误信息
return render(request, ‘polls/detail.html’, {
‘question’: question,
‘error_message’: “You didn’t select a choice.”,
})
else:
# 增加选中选项的票数并保存
selected_choice.votes += 1
selected_choice.save()
# 成功处理 POST 数据后,始终返回 HttpResponseRedirect
# 这可以防止用户点击后退按钮时重复提交表单
# reverse() 函数根据 URL 名称和参数生成 URL 路径
# 例如 reverse(‘polls:results’, args=(question.id,)) 会生成类似 ‘/polls/1/results/’ 的路径
return HttpResponseRedirect(reverse(‘polls:results’, args=(question.id,)))

“`

为了让这些新视图能够工作,你还需要:

  1. 更新 polls/urls.py 添加对应的 URL 模式:
    “`python
    # polls/urls.py
    from django.urls import path
    from . import views

    app_name = ‘polls’
    urlpatterns = [
    path(”, views.index, name=’index’),
    # ex: /polls/5/
    path(‘/’, views.detail, name=’detail’),
    # ex: /polls/5/results/
    path(‘/results/’, views.results, name=’results’),
    # ex: /polls/5/vote/
    path(‘/vote/’, views.vote, name=’vote’),
    ]
    ``
    这里的
    是路径转换器,它会匹配一个整数并将其作为question_id` 参数传递给视图函数。

  2. 创建对应的模板文件 (polls/templates/polls/detail.htmlpolls/templates/polls/results.html)。

    • detail.html 需要包含一个 HTML 表单,让用户选择选项并提交到 vote 视图的 URL。
    • results.html 用于显示投票结果。

    示例 polls/templates/polls/detail.html:
    “`html

    {{ question.question_text }}

    {% if error_message %}

    {{ error_message }}

    {% endif %}

    {% csrf_token %}
    {% for choice in question.choice_set.all %}


    {% endfor %}

    ``
    注意
    {% url ‘polls:vote’ question.id %}的用法,它通过 URL 名称反向解析出实际的 URL,使 URL 配置更具灵活性。{% csrf_token %}` 用于防止跨站请求伪造攻击,在所有处理 POST 请求的表单中都必须包含。

    示例 polls/templates/polls/results.html:
    “`html

    {{ question.question_text }}

      {% for choice in question.choice_set.all %}

    • {{ choice.choice_text }} — {{ choice.votes }} vote{{ choice.votes|pluralize }}
    • {% endfor %}

    Vote again?

    Back to poll list
    “`


7. 强大的 Django Admin 后台

Django Admin 是其最强大的功能之一。只需少量配置,就能为你的模型提供一个功能完善的管理界面。

7.1 创建超级用户

首先,你需要创建一个可以登录 Admin 后台的用户。在命令行运行:

bash
python manage.py createsuperuser

按照提示输入用户名、邮箱(可选)和密码。

7.2 注册模型到 Admin

要让你的模型出现在 Admin 界面中,需要在应用的 admin.py 文件中注册它们。打开 polls/admin.py 并修改:

“`python

polls/admin.py

from django.contrib import admin
from .models import Question, Choice # 导入你的模型

注册 Question 模型

admin.site.register(Question)

注册 Choice 模型 (可选,通常关联的模型会在主模型页面内联显示)

admin.site.register(Choice)
“`

7.3 访问 Admin 后台

确保开发服务器正在运行 (python manage.py runserver)。
在浏览器中访问 http://127.0.0.1:8000/admin/
使用你刚刚创建的超级用户凭据登录。

登录后,你会看到一个管理界面,其中包含了 “Polls” 应用以及你注册的 “Questions” 和 “Choices” 模型。你可以点击它们来添加、修改、删除数据。

7.4 定制 Admin 界面 (可选)

Django Admin 的显示方式可以高度定制。例如,你可以在 Question 列表页显示 pub_date,或者在 Question 编辑页内联显示和编辑关联的 Choices。

修改 polls/admin.py

“`python

polls/admin.py

from django.contrib import admin
from .models import Question, Choice

定义 Choice 的内联显示方式

class ChoiceInline(admin.TabularInline): # 或者 admin.StackedInline
model = Choice
extra = 3 # 默认显示 3 个空的 Choice 表单

定义 Question 的 Admin 配置

class QuestionAdmin(admin.ModelAdmin):
# 在列表页显示的字段
list_display = (‘question_text’, ‘pub_date’, ‘was_published_recently’)
# 添加过滤选项
list_filter = [‘pub_date’]
# 添加搜索框,按 question_text 字段搜索
search_fields = [‘question_text’]
# 将字段分组显示在编辑页
fieldsets = [
(None, {‘fields’: [‘question_text’]}),
(‘Date information’, {‘fields’: [‘pub_date’], ‘classes’: [‘collapse’]}), # 可折叠
]
# 在 Question 编辑页内联显示 Choice
inlines = [ChoiceInline]

注册 Question 时使用自定义的 QuestionAdmin 配置

admin.site.register(Question, QuestionAdmin)

因为 Choice 在 QuestionAdmin 中内联显示了,通常不再需要单独注册 Choice

admin.site.register(Choice)

“`

刷新 Admin 页面,你会看到应用了新配置的界面。


8. 处理静态文件 (CSS, JavaScript, 图片)

静态文件是指那些不需要服务器动态生成的文件,如 CSS 样式表、JavaScript 脚本、图片、字体等。

8.1 配置

Django 需要知道去哪里查找静态文件,以及在 URL 中如何引用它们。

  • STATIC_URL (已在默认 settings.py 中设置)
    这是引用静态文件时使用的 URL 前缀。例如,设置为 /static/,那么 css/style.css 文件对应的 URL 就是 /static/css/style.css
    python
    # mysite/settings.py
    STATIC_URL = 'static/'

  • STATICFILES_DIRS (需要手动添加)
    告诉 Django 除了在每个应用的 static/ 目录下查找静态文件外,还在哪些额外的目录查找。通常用于存放项目级别的静态文件。在 mysite/settings.py 中添加:
    “`python
    # mysite/settings.py
    import os # 确保导入 os 模块

    STATICFILES_DIRS = [
    os.path.join(BASE_DIR, ‘static’), # 在项目根目录下创建一个名为 ‘static’ 的文件夹
    ]
    ``BASE_DIR` 是 Django 自动计算的项目根目录路径。

  • STATIC_ROOT (主要用于生产环境)
    这是运行 python manage.py collectstatic 命令时,所有静态文件会被收集到的目标目录不要将你的源静态文件放在这里。这个目录应该只由 collectstatic 命令管理。在部署时,Web 服务器(如 Nginx)会被配置为从 STATIC_ROOT 目录提供静态文件服务。
    python
    # mysite/settings.py (通常只在部署配置中设置)
    # STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

8.2 创建和组织静态文件

遵循约定,将应用的静态文件放在应用目录下的 static/app_name/ 子目录中,项目级别的静态文件放在 STATICFILES_DIRS 指定的目录(例如项目根目录下的 static/)中。

例如,为 polls 应用创建一个 CSS 文件:

polls/
├── static/
│ └── polls/
│ └── style.css <-- 创建这个文件
├── templates/
...

polls/static/polls/style.css 中添加一些样式:

“`css
/ polls/static/polls/style.css /
body {
background-color: lightblue;
}

li a {
color: green;
}
“`

8.3 在模板中使用静态文件

在模板中加载和引用静态文件,需要使用 static 模板标签。

首先,在模板文件的顶部加载 static 标签库:
{% load static %}

然后,使用 static 标签生成静态文件的 URL:
{% static 'path/to/your/file' %}

修改 polls/templates/polls/index.html 来加载 CSS 文件:

“`html

{% load static %}




Polls Index

{{ question_text|default:”List of Polls” }}

{% if latest_question_list %}

{% else %}

No polls are available.

{% endif %}

“`

测试:
确保开发服务器运行中。刷新 http://127.0.0.1:8000/polls/ 页面。你应该看到背景变成了浅蓝色,链接变成了绿色。Django 的开发服务器会自动处理静态文件的服务(只要 DEBUG = True 并且 django.contrib.staticfilesINSTALLED_APPS 中)。

collectstatic 命令

在生产环境中部署时,你需要运行 python manage.py collectstatic。这个命令会查找所有 INSTALLED_APPSstatic/ 目录以及 STATICFILES_DIRS 指定的目录,并将所有找到的静态文件复制到 STATIC_ROOT 指定的目录下。然后你需要配置你的 Web 服务器(如 Nginx)来直接从 STATIC_ROOT 提供 /static/ URL 的服务,这样效率更高。


9. 处理表单 (Forms)

Web 表单是用户与网站交互的主要方式之一。Django 提供了一个强大的表单处理系统,可以处理表单渲染、数据验证和数据清理。

我们在之前的 vote 视图中直接处理了 request.POST 数据,但这不够健壮。使用 Django Forms 可以简化这个过程。

9.1 创建表单类

polls 应用目录下创建一个新文件 forms.py

“`python

polls/forms.py

from django import forms
from .models import Choice

这是一个简单的表单,但通常我们会使用 ModelForm 来直接从模型生成表单

class VoteForm(forms.Form):

# 这里可以定义表单字段,例如使用 ChoiceField

# choice = forms.ModelChoiceField(queryset=Choice.objects.none(), widget=forms.RadioSelect, empty_label=None)

# def init(self, args, *kwargs):

# question = kwargs.pop(‘question’, None)

# super().init(args, *kwargs)

# if question:

# self.fields[‘choice’].queryset = question.choice_set.all()

pass # 对于我们的投票场景,直接在模板中渲染更直观,这里暂时留空或不创建

“`

对于 polls 示例中的投票场景,由于选项是动态关联到特定问题的,直接在模板中使用 HTML 表单并配合视图逻辑处理 request.POST 是一种常见且直接的方式(如 detail.htmlvote 视图所示)。

让我们考虑一个更典型的表单使用场景:创建一个联系表单。

假设我们有一个新的应用 contact

  1. 创建应用: python manage.py startapp contact
  2. 添加到 INSTALLED_APPS: 'contact.apps.ContactConfig'
  3. 创建 contact/forms.py:
    “`python
    # contact/forms.py
    from django import forms

    class ContactForm(forms.Form):
    name = forms.CharField(max_length=100, required=True, label=”Your Name”)
    email = forms.EmailField(required=True, label=”Your Email”)
    subject = forms.CharField(max_length=100, required=True)
    message = forms.CharField(widget=forms.Textarea, required=True)
    ``
    这里我们定义了一个包含姓名、邮箱、主题和消息的表单。Django 提供了多种表单字段(
    CharField,EmailField,IntegerField,BooleanField等)和控件(widget`)。

  4. 创建视图 (contact/views.py):
    “`python
    # contact/views.py
    from django.shortcuts import render, redirect
    from django.core.mail import send_mail
    from .forms import ContactForm

    def contact_view(request):
    if request.method == ‘POST’:
    # 如果是 POST 请求,用提交的数据实例化表单
    form = ContactForm(request.POST)
    if form.is_valid(): # 检查数据是否有效(根据表单定义)
    # 数据有效,获取清理后的数据
    name = form.cleaned_data[‘name’]
    email = form.cleaned_data[’email’]
    subject = form.cleaned_data[‘subject’]
    message = form.cleaned_data[‘message’]

            # 在这里执行操作,例如发送邮件
            # send_mail(
            #     f"Message from {name}: {subject}",
            #     message,
            #     email, # 发件人邮箱 (或者使用 settings.EMAIL_HOST_USER)
            #     ['[email protected]'], # 收件人列表
            # )
    
            # 重定向到成功页面或显示成功信息
            return redirect('contact:success') # 需要定义名为 'success' 的 URL
    else:
        # 如果是 GET 请求(首次访问页面),创建一个空表单
        form = ContactForm()
    
    # 渲染模板,并将表单传递给模板
    return render(request, 'contact/contact.html', {'form': form})
    

    def success_view(request):
    # 简单的成功页面视图
    return render(request, ‘contact/success.html’)
    “`

  5. 创建模板 (contact/templates/contact/contact.html):
    “`html

    {% extends ‘base.html’ %}

    {% block content %}

    Contact Us

    {% csrf_token %}
    {{ form.as_p }}



    {% endblock %}
    创建 `contact/templates/contact/success.html`:html

    {% extends ‘base.html’ %}
    {% block content %}

    Thank You!

    Your message has been sent successfully.

    {% endblock %}
    ``
    (你还需要创建一个基础模板
    templates/base.html` 供继承)

  6. 配置 URL (contact/urls.pymysite/urls.py):
    “`python
    # contact/urls.py
    from django.urls import path
    from . import views

    app_name = ‘contact’
    urlpatterns = [
    path(”, views.contact_view, name=’contact’),
    path(‘success/’, views.success_view, name=’success’),
    ]
    python

    mysite/urls.py

    from django.contrib import admin
    from django.urls import path, include

    urlpatterns = [
    path(‘admin/’, admin.site.urls),
    path(‘polls/’, include(‘polls.urls’)),
    path(‘contact/’, include(‘contact.urls’)), # 添加 contact 应用的 URL
    ]
    “`

现在访问 /contact/ 就会显示联系表单,提交后会进行验证,成功则重定向到 /contact/success/

ModelForm

如果你的表单直接对应一个数据库模型,使用 ModelForm 会更方便。它能根据模型自动生成表单字段。

例如,如果我们想创建一个表单来添加 Question

“`python

polls/forms.py

from django import forms
from .models import Question

class QuestionForm(forms.ModelForm):
class Meta:
model = Question # 指定关联的模型
fields = [‘question_text’, ‘pub_date’] # 指定包含在表单中的字段
# 或者使用 exclude = [‘field_to_exclude’] 来排除字段
widgets = { # 可以为特定字段指定不同的 HTML 控件
‘pub_date’: forms.DateTimeInput(attrs={‘type’: ‘datetime-local’}),
}
``
然后你可以在视图中使用这个
QuestionForm来创建和更新Question对象,form.save()` 方法可以直接将表单数据保存到数据库。


10. 后续学习建议

恭喜你!你已经完成了 Django 入门的初步探索,了解了其核心概念和基本工作流程。但这仅仅是个开始,Django 的世界广阔而深邃。

下一步可以探索:

  1. 官方文档(Django Documentation): 这是最权威、最全面的资源。务必阅读官方教程(比本文更深入),并查阅各个组件(模型、视图、模板、表单、Admin等)的详细指南。(https://docs.djangoproject.com/en/stable/)
  2. 类视图(Class-Based Views, CBVs): Django 提供了基于类的视图,用于处理常见的 Web 开发模式(如显示列表、详情、创建、更新、删除对象),可以使代码更结构化和可重用。
  3. 用户认证与授权: 学习 Django 内置的 django.contrib.auth 系统,实现用户注册、登录、登出、密码管理和权限控制。
  4. 数据库查询进阶: 深入理解 Django ORM 的查询 API,包括复杂的过滤、聚合(Aggregation)、注解(Annotation)、F 对象和 Q 对象等。
  5. 测试(Testing): 学习如何为你的 Django 应用编写单元测试和集成测试,确保代码质量和稳定性。
  6. 部署(Deployment): 学习如何将你的 Django 应用部署到生产环境,涉及 WSGI/ASGI 服务器(如 Gunicorn, Uvicorn)、Web 服务器(如 Nginx, Apache)、数据库配置、静态文件处理、环境变量管理等。
  7. Django REST framework (DRF): 如果你需要构建 Web API(例如为前端框架如 React/Vue/Angular 或移动应用提供数据接口),DRF 是一个非常流行且强大的选择。
  8. 第三方包和生态系统: 探索 Django 庞大的第三方包生态,找到满足特定需求的库(如 Celery 用于异步任务,Django Debug Toolbar 用于调试等)。
  9. 项目实践: 动手做项目是最好的学习方式。尝试构建一个博客、在线商店、社交媒体应用或其他你感兴趣的 Web 应用。

结语

Django 是一个功能强大且设计优雅的 Web 框架。虽然初看起来涉及的概念较多,但其清晰的结构和丰富的内置功能使得开发过程高效而愉快。希望这篇详尽的入门指南能为你打下坚实的基础,并激发你继续深入学习 Django 的兴趣。

记住,编程学习是一个持续实践和探索的过程。不断编码,不断查阅文档,不断尝试新功能,你将逐渐掌握 Django 并能用它构建出色的 Web 应用。祝你 Django 之旅顺利!

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部