Django入门教程:搭建你的第一个Python网站

代码旅人
2025-06-15 21:37
阅读 223

开篇:一次从零到一的旅程

去年年底,公司需要做一个内部使用的项目管理工具,用于替代当时用Excel表格管理需求和任务的方式。作为一个技术负责人,我决定采用Django来搭建这个小系统——毕竟它以“开箱即用”著称,开发效率高,而且我们团队对Python也比较熟悉。这是我第一次完整使用Django做项目的后端,虽然不是什么复杂的项目,但在过程中确实踩了不少坑,也积累了一些经验。

今天我想分享这段经历,带你一步步用 Django 搭建一个属于自己的网站。我会结合真实场景,边讲边写代码,并且重点讲述我在实际工作中遇到的问题和解决方案。如果你是 Python 新手、或者刚准备接触 Web 开发,这篇文章应该能给你带来不少帮助。


问题描述:为什么选择 Django?

其实最开始,我也考虑过用 Flask 或者 FastAPI,因为它们更轻量级、灵活性更高。但仔细想想,Flask 太自由了,反而容易在初期投入大量时间去搭架子;而 FastAPI 虽然好,但我们项目里涉及大量的表单提交、后台管理界面这些功能,FastAPI 并不像 Django 那样天然支持这些。

更重要的是,我们的项目中用户权限、角色控制、日志记录等功能都是刚需。Django 内置的 Admin 管理后台简直就是为这种需求量身定做的。再加上 ORM 的强大和社区文档的丰富程度,我最终选择了 Django 来作为这次项目的技术栈。

不过说实话,虽然我对 Python 很熟,但真正上手用 Django 做全栈项目还是头一遭。从创建第一个 app 开始,我就遇到了一系列问题:

  • 项目结构怎么组织?
  • URL 怎么配置才合理?
  • 数据库模型如何设计?
  • 表单怎么处理?
  • 前端模板怎么和后端对接?
  • 如何部署上线?

别急,这些问题我都一个一个地解决了,下面我将带你从0到1搭建一个完整的项目。


解决方案:快速启动你的 Django 项目

我们先从最基础的部分讲起:安装 Django 并创建一个项目。

1. 安装 Django

推荐你使用虚拟环境(virtual environment)来管理依赖,这样可以避免不同项目之间的依赖冲突。

python -m venv venv
source venv/bin/activate  # Windows 上使用 venv\Scripts\activate
pip install django

安装完成后,可以用如下命令验证是否安装成功:

django-admin --version

2. 创建项目

接着使用 django-admin 快速生成项目骨架:

django-admin startproject mysite
cd mysite

目录结构如下:

mysite/
├── manage.py
└── mysite/
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

我们可以先启动本地服务器看看效果:

python manage.py runserver

访问 http://127.0.0.1:8000,你会看到熟悉的 "The install worked successfully! Congratulations!" 页面,说明一切正常。


项目背景:我们需要什么样的网站?

回到我们最初的业务场景:我们要搭建一个项目管理系统,用于管理项目成员、任务分配、状态变更等功能。

简单来说,系统至少要满足以下功能:

  • 用户登录认证(Django 自带认证系统)
  • 创建项目 & 查看项目列表
  • 添加任务、修改任务状态(未开始 / 进行中 / 已完成)
  • 分配任务给团队成员
  • 后台管理页面自动更新数据(Django Admin)

所以接下来,我们将围绕这个功能展开构建。


开启第一个 App —— tasks

Django 鼓励开发者将功能模块化,每个功能对应一个 app。我们创建一个叫 tasks 的 app 来管理所有与任务相关的内容:

python manage.py startapp tasks

然后在 settings.py 中注册这个 app:

INSTALLED_APPS = [
    ...
    'tasks.apps.TasksConfig',
]

设计数据库模型

我们要设计两个核心模型:ProjectTask

打开 tasks/models.py,写入以下内容:

from django.db import models
from django.contrib.auth.models import User

class Project(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name

class Task(models.Model):
    STATUS_CHOICES = (
        ('P', 'Pending'),
        ('IP', 'In Progress'),
        ('C', 'Completed'),
    )
    
    title = models.CharField(max_length=100)
    description = models.TextField(blank=True, null=True)
    project = models.ForeignKey(Project, on_delete=models.CASCADE)
    assignee = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    status = models.CharField(max_length=2, choices=STATUS_CHOICES, default='P')
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

这里有几个关键点需要注意:

  1. 外键关系:任务归属项目(Project),同时分配给用户(User)。
  2. 默认值设置:通过 default 参数设置初始状态为 Pending。
  3. 空值处理:描述字段允许为空,便于前端展示。
  4. on_delete 设置:当项目或用户被删除时,任务如何处理?这里设为 SET_NULL,表示保留任务但取消关联。

保存之后执行迁移命令:

python manage.py makemigrations
python manage.py migrate

实现视图与模板:让数据动起来

接下来我们实现一些基本的视图(views)和模板(templates),用来展示项目和任务数据。

首先,我们在 tasks/views.py 中编写首页视图:

from django.shortcuts import render
from .models import Project, Task

def home(request):
    projects = Project.objects.all()
    tasks = Task.objects.select_related('project', 'assignee').all()
    context = {
        'projects': projects,
        'tasks': tasks
    }
    return render(request, 'tasks/home.html', context)

注意几点优化:

服务器部署方案-2

  • 使用 select_related() 提前加载外键对象,防止 N+1 查询问题。
  • 把所有项目和任务数据传入模板进行渲染。

然后我们创建 HTML 模板。在项目根目录下新建 templates/tasks 文件夹,创建 home.html

<!-- templates/tasks/home.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My Project Manager</title>
</head>
<body>
    <h1>Projects</h1>
    <ul>
        {% for project in projects %}
            <li>{{ project.name }}</li>
        {% endfor %}
    </ul>

    <h1>Tasks</h1>
    <table border="1">
        <tr><th>Title</th><th>Status</th><th>Assignee</th></tr>
        {% for task in tasks %}
            <tr>
                <td>{{ task.title }}</td>
                <td>{{ task.get_status_display }}</td>
                <td>{{ task.assignee.username|default:"Unassigned" }}</td>
            </tr>
        {% endfor %}
    </table>
</body>
</html>

服务器部署方案-1

现在还需要在 settings.py 中配置模板路径:

TEMPLATES = [
    {
        ...
        'DIRS': [BASE_DIR / 'templates'],
        ...
    },
]

接着,在主应用目录下的 urls.py 添加路由:

from django.urls import path
from tasks.views import home

urlpatterns = [
    path('', home, name='home'),
]

重启服务之后访问 /,你应该能看到所有项目的名称和任务列表!


实现表单功能:添加项目和任务

Django 提供了强大的 Form 类型来简化表单处理流程。我们可以为添加项目和任务分别创建对应的 form。

tasks/forms.py 中添加:

from django import forms
from .models import Project, Task

class ProjectForm(forms.ModelForm):
    class Meta:
        model = Project
        fields = ['name', 'description']

class TaskForm(forms.ModelForm):
    class Meta:
        model = Task
        fields = ['title', 'description', 'project', 'assignee', 'status']

然后在 views.py 添加新视图:

from .forms import ProjectForm, TaskForm

def add_project(request):
    if request.method == 'POST':
        form = ProjectForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('home')
    else:
        form = ProjectForm()
    return render(request, 'tasks/add_form.html', {'form': form, 'title': 'Add Project'})

def add_task(request):
    if request.method == 'POST':
        form = TaskForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('home')
    else:
        form = TaskForm()
    return render(request, 'tasks/add_form.html', {'form': form, 'title': 'Add Task'})

再写一个通用的模板 add_form.html

{% extends "base.html" %}

{% block content %}
<h1>{{ title }}</h1>
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Save</button>
</form>
{% endblock %}

以及一个简单的 base.html 模板放在 templates 根目录:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <div class="container">
        {% block content %}{% endblock %}
    </div>
</body>
</html>

最后在 urls.py 中添加路径:

path('project/new/', views.add_project, name='add_project'),
path('task/new/', views.add_task, name='add_task'),

测试一下访问 /project/new//task/new/,填写表单后跳转回主页,就能看到数据已经正确入库了!


踩过的几个坑与解决方案

在整个开发过程中,我确实踩了几个比较典型的坑,这里分享出来给大家避个雷。

✅ 1. 模板找不到怎么办?

刚开始的时候总提示 TemplateDoesNotExist 错误,检查模板路径发现没有配置 TEMPLATES.DIRS。记得一定要在 settings.py 中加上你的模板根目录路径,否则 Django 默认只会查找每个 app 下的 templates 目录。

✅ 2. 表单提交失败,页面没反应

这种情况通常是 CSRF token 缺失导致的。确保你在模板中加入 {% csrf_token %},并且使用 POST 请求发送数据。Django 对安全性要求很高,不加的话会直接拒绝请求。

✅ 3. 外键字段显示用户名而不是ID

Django 在展示 ForeignKey 字段时,默认会显示 ID,但这对用户很不友好。有两种办法解决:

  1. 使用 __str__ 方法返回可读名,比如我们在模型里写了 return self.name
  2. 在模板中使用 {{ obj.field.related_name }},比如 {{ task.assignee.username }}

✅ 4. 迁移文件冲突或出错

有时候执行 makemigrations 会报错,尤其是在多人协作或版本切换频繁的情况下。可以尝试删除所有 migrations 文件(除了 __init__.py)和数据库中的 django_migrations 表,再重新运行迁移。当然这只能在开发阶段用,生产环境慎操作。


效果总结:我们的网站跑起来了!

经过上面这一系列步骤,我们已经成功用 Django 构建了一个具有基础 CRUD 功能的任务管理系统。它的优点包括:

  • 开发速度快,借助 Admin 系统和 ORM,不需要自己写很多 SQL;
  • 结构清晰,模块化程度高;
  • 易于维护和扩展,未来加上权限管理、日历提醒、邮件通知等都不是问题;
  • 生产可用性强,配合 Gunicorn + Nginx 可以上线。

对于我们内部使用的小工具来说,这套系统已经非常够用了。更重要的是,整个过程教会了我如何快速构建一个可靠的 Django 应用,并解决各种现实问题。


我的几个建议:新手入门 Django 的注意事项

作为一个走过弯路的人,想给正在学习 Django 的朋友几个建议:

  1. 别怕官方文档,它是最好的资源:Django 官方文档写得非常详细,而且更新频率高。有问题多查文档,比找 Stack Overflow 更准确。
  2. 善用 Django Admin 系统:这是 Django 最大的优势之一,不仅能快速实现数据管理,还能节省大量的开发工作。
  3. 学会使用调试器:在 VSCode 或 PyCharm 中启用断点调试是非常有必要的。有些逻辑错误光靠 print 是很难定位的。
  4. 提前规划 URL 结构:URL 是网站的入口,一开始设计不好后面改起来会很痛苦。建议采用 RESTful 风格。
  5. 性能也要考虑:虽然 Django 很快,但在并发较高的时候也可能出现瓶颈。可以考虑引入缓存机制(如 Redis)、异步任务队列(如 Celery)来优化。
  6. 部署时注意静态资源:Django 不擅长处理静态文件,建议用 Nginx 来托管 CSS/JS/images,Gunicorn 跑 Django 本身。

后记:Django 仍然是现代 Web 开发的利器

虽然现在前端框架层出不穷,Node.js、Go、Rust 也开始在 Web 后端崭露头角,但我始终认为,Django 依然是中小型项目中最实用的选择之一。它不仅降低了开发门槛,更重要的是能够让我们专注于业务逻辑本身,而不是陷入底层细节中。

如果你是一个刚刚踏入后端开发领域的新手,或者想要尝试用 Python 做一个完整的网站,Django 无疑是一条正确的入门之路。

希望我的这篇分享对你有所帮助。如果有什么问题,欢迎留言交流。咱们一起进步!

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝