从“Hello World”到上线部署:用Django搭建我的第一个Python网站实战总结

超凡之创造者
2025-06-23 17:09
阅读 216

开篇:为什么是Django?

开篇:为什么是Django?

我在一家中型互联网公司担任后端开发工程师,主要负责数据平台和内部系统的开发与维护。虽然日常工作中更多使用Go或Node.js构建高并发的服务,但在一些中小项目、快速验证场景下,我更倾向于使用Django——Python生态中最成熟、最稳定的Web框架之一。

去年我们部门需要搭建一个面向内容运营的后台管理系统(CMS),用于管理文章发布、活动配置和基础数据分析。团队成员技术栈参差不齐,且时间紧迫,我们需要在两周内交付原型并启动迭代。这时候,Django凭借其“开箱即用”的特性、ORM的强大易用性以及完善的Admin系统,成了我们技术选型的重点。

这篇文章将结合我那次项目的实际经历,手把手带你完成一个简单的Django项目搭建,并分享我在这个过程中踩过的坑和收获的经验。


项目背景:为什么选择用Django做这个项目?

项目背景:为什么选择用Django做这个项目?

我们当时要做的系统其实功能并不复杂:

  • 运营同学可以新增/编辑文章
  • 设置文章封面图和状态(草稿 / 发布)
  • 管理活动页面的基本信息(标题、描述、开始结束时间等)
  • 统计每日文章数量和点击量

之所以没有选用现成的WordPress之类的内容管理工具,是因为我们希望系统能更好地接入公司内部的权限系统、用户中心服务,以及后续的分析系统。

最终我们的团队决定采用Django + Bootstrap的方式搭建一套轻量级CMS后台,目标是:

  1. 快速出原型并可直接上生产环境跑;
  2. 提供API供前端调用(前后端分离的雏形);
  3. 后期方便扩展统计模块和其他业务模块。

搭建过程:一步步从零开始

Step 1:准备开发环境

首先创建虚拟环境:

python -m venv venv
source venv/bin/activate

然后安装Django:

pip install django

查看当前版本是否符合预期:

django-admin --version

建议使用稳定版,比如我现在用的是 Django 4.2 LTS 版本,因为我们要部署到生产环境,LTS版本在安全性上有保障。

Step 2:创建项目结构

接下来,生成基本项目骨架:

django-admin startproject cms_project
cd cms_project
python manage.py runserver

默认会开启本地服务器监听8000端口,访问 http://localhost:8000 就可以看到 Django 的欢迎页了。说明你的基础环境搭建成功!

但还不能满足我们的需求,我们还需要创建自己的应用(application)。Django推荐每个功能模块是一个app,所以这里我们创建两个app:一个是文章管理(articles),一个是活动管理(activities)。

python manage.py startapp articles
python manage.py startapp activities

记得在 cms_project/settings.py 中添加这两个应用到 INSTALLED_APPS 里:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'articles',
    'activities',
]

Step 3:设计数据库模型(Articles)

以文章为例,我们在 articles/models.py 中定义 Article 类:

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

class Article(models.Model):
    STATUS_CHOICES = (
        ('draft', 'Draft'),
        ('published', 'Published'),
    )

    title = models.CharField(max_length=255)
    content = models.TextField()
    cover_image = models.ImageField(upload_to='covers/')
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title

接着执行迁移:

python manage.py makemigrations
python manage.py migrate

此时你会在本地看到 db.sqlite3 文件,这是Django默认的SQLite数据库,适合本地开发调试。当然在正式环境中我们肯定不会用它,后面会讲生产环境配置。

Step 4:注册Admin后台

Django自带的Admin系统真的非常强大,特别是在快速搭建后台的时候简直是神器。

打开 articles/admin.py,加入以下代码:

from django.contrib import admin
from .models import Article

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'status', 'created_at')
    list_filter = ('status', 'created_at')
    search_fields = ('title', 'content')
    prepopulated_fields = {'slug': ('title',)}

这时运行一下 server:

python manage.py runserver

访问 http://localhost:8000/admin,你就能看到文章的管理界面了!是不是超级快?

不过要注意几点:

  • 默认用户名密码是在数据库中存储的,需要用命令创建管理员:

    python manage.py createsuperuser
    
  • 如果你在公司有统一的身份认证系统,比如OAuth2或者LDAP,可能需要自己集成SSO登陆系统,这部分我们后面再展开。

Step 5:开发RESTful接口

虽说Django本身是MVC框架,但为了支持未来前端调用API的需求,我们采用了 Django REST framework (DRF) 来开发REST API。

安装 DRF:

pip install djangorestframework

同样在 settings.py 添加:

INSTALLED_APPS += ['rest_framework']

然后写一个简单的文章接口(views.py):

from rest_framework import viewsets
from .models import Article
from .serializers import ArticleSerializer

class ArticleViewSet(viewsets.ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

还要写一个序列化器(serializers.py):

from rest_framework import serializers
from .models import Article

class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = '__all__'

最后,在主URL中引入路由(cms_project/urls.py):

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from articles.views import ArticleViewSet

router = DefaultRouter()
router.register(r'articles', ArticleViewSet)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include(router.urls)),
]

现在你可以访问 /api/articles/ 接口了。GET、POST、PUT、DELETE 都已经支持!

不过这只是个起点,真正上线时还需要考虑分页、过滤、权限控制等内容。我们后面会提到这些要点。


遇到的问题与挑战

尽管Django为我们提供了很多开箱即用的功能,但在实际部署和使用过程中也遇到了不少问题,以下是我遇到的几个典型挑战:

挑战一:图片上传路径配置

我们在开发环境上传图片没问题,但上了测试环境发现找不到图片。后来排查发现,我们用的 ImageField 默认会把文件保存在项目根目录下的指定路径,而生产环境静态文件是通过Nginx处理的,没设置好就会404。

解决方法:设置MEDIA_ROOT和MEDIA_URL:

# settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

并在urls.py中临时启用媒体文件服务(仅限开发环境):

from django.conf.urls.static import static
from django.conf import settings

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

生产环境则通过Nginx配置代理:

location /media {
    alias /path/to/media;
}

挑战二:数据库性能瓶颈

随着文章数量增加到上千条,列表展示速度明显变慢。起初我们用了默认的 Article.objects.all() 做查询,结果导致大量不必要的JOIN操作。

解决方案:

  • 使用 select_related()prefetch_related() 减少SQL查询次数
  • 对搜索字段加上索引(尤其是text类型,不要忘记创建GIN索引)
  • 分页处理(限制单页展示数目)

挑战三:跨域请求问题

前后端分离后,前端页面部署在另一个域名下,第一次发请求就报错 CORS。

解决方式:使用 django-cors-headers 插件来统一处理CORS问题。

安装:

pip install django-cors-headers

添加中间件:

MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]

CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = [
    "http://frontend.example.com",
]

这样就可以控制哪些域名可以访问API了。


上线部署经验分享

1. 数据库选择:别再用 SQLite

开发阶段用 SQLite 完全没问题,但在生产环境一定要换成 PostgreSQL 或 MySQL,否则你将会面对并发写入失败、锁表、性能低下等各种问题。

我们项目最终选择了 PostgreSQL,并配合 Django 的内置 ORM 很好地完成了任务。

配置数据库只需修改 settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydb',
        'USER': 'myuser',
        'PASSWORD': 'mypassword',
        'HOST': 'db-hostname',
        'PORT': '5432',
    }
}

另外,线上环境务必关闭 DEBUG = False,否则会有安全隐患!

2. 部署方式建议:Gunicorn + Nginx + Supervisor

Django自带的runserver只适合开发环境,生产环境我们一般用 Gunicorn 处理 WSGI 请求,配合 Nginx 反向代理实现高性能 Web 服务。

简单流程:

  1. 安装 Gunicorn:

    pip install gunicorn
    
  2. 编写 WSGI 应用入口(一般已由Django帮你生成)

  3. 启动 Gunicorn:

    gunicorn --bind 0.0.0.0:8000 cms_project.wsgi
    
  4. 配置 Nginx 作为反向代理(示例):

    server {
        listen 80;
    
        location / {
            proxy_pass http://127.0.0.1:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    
        location /static/ {
            alias /path/to/static/;
        }
    
        location /media/ {
            alias /path/to/media/;
        }
    }
    
  5. 使用 Supervisor 管理进程,防止服务崩溃或重启机器后自动恢复。

Supervisor配置示例:

[program:cms_project]
command = /path/to/venv/bin/gunicorn --workers 3 cms_project.wsgi
directory = /path/to/cms_project
autostart=true
autorestart=true
stderr_logfile=/var/log/cms_project.err.log
stdout_logfile=/var/log/cms_project.out.log

一些小技巧 & 经验分享

技巧一:充分利用 Admin

Django Admin 是非常强大的工具。对于中小型后台系统来说,几乎能满足所有CRUD需求。可以通过继承 ModelAdmin 并重写各种方法来自定义展示和行为。

例如:

  • 列表页添加筛选器
  • 自定义保存逻辑
  • 增加额外动作(批量删除、导出CSV)
  • 控制字段权限(某些字段只能特定角色编辑)

技巧二:合理使用缓存

对于频繁读取的数据(如文章详情页、统计数据),我们采用了 cache_page 装饰器进行局部缓存,有效减少数据库压力。

from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page

@method_decorator(cache_page(60 * 5), name='dispatch')
class ArticleDetailView(DetailView):
    ...

这样可以让同一个文章在5分钟内重复访问时直接从内存缓存返回,而不是再去查一次数据库。

技巧三:日志记录 & 异常上报

我们集成了 Sentry 监控整个Django服务的异常情况,并开启了详细的日志输出,包括SQL语句(只用于调试)、请求参数、错误堆栈等。

配置示例(settings.py):

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'root': {
        'handlers': ['console'],
        'level': 'INFO',
    },
}

负载均衡配置-1

生产环境建议将日志输出到文件或集中日志平台(如 ELK Stack)。


最终效果和收益

项目上线后,整个运营团队都反馈说使用体验不错,比之前用Excel手动更新内容高效太多了。

技术层面的收益也很明显:

  • 两周内完成原型并上线
  • 支持后续接口调用扩展
  • 易于维护和二次开发
  • 成为后续其他内部系统的基础模板

更重要的是,通过这次实践让我对Django在快速开发和生产环境部署方面的能力有了更深的认识。


总结:给想入门Django的同学的建议

如果你刚接触Django,建议从一个小项目开始练手,比如博客、任务管理系统、简易CMS等。

以下是我的几点建议:

  1. 先理解MTV架构思想:Django本质是MTV模式,掌握好Template、View、Model的关系是关键。
  2. 多看官方文档:Django的官方文档是最好的学习资源,语言清晰、结构完整、例子丰富。
  3. 善用第三方插件:比如DRF、django-taggit、django-cors-headers等都能极大提升开发效率。
  4. 注意安全配置:上线前必须关闭DEBUG、设置合适权限、加密敏感数据、防止XSS攻击。
  5. 性能从第一天就要考虑:虽然Django默认够用,但在高并发下需要优化查询、合理使用缓存。
  6. 保持代码简洁和模块化:每个app尽量单一职责,避免后期难以维护。

Django不是万能的,但它是一个非常适合初学者和中小项目的技术栈。尤其是在需要兼顾开发效率和稳定性的场景下,它的优势非常明显。

希望这篇真实案例分享能帮到正在学习Django的你,也希望你能用Django做出属于自己的第一个网站!


文章作者:老杨,某互联网公司后端开发工程师。喜欢折腾开源项目,热爱写作和分享。GitHub @xiaoyang-dev,欢迎交流。

评论 0

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