models.py

孙娜_移动端
2025-06-17 19:41
阅读 580

从零开始,用Django搭建我的第一个Python网站

大家好,我是张工,在一家互联网公司负责后端开发。最近我在参与一个内部项目时,尝试使用 Django 构建了一个简单的 Python 网站。这是我在工作中首次深度接触 Django 框架,从一开始的懵懂到后来逐渐上手,整个过程充满了挑战和收获。

今天我想分享一下这段经历——包括我为什么选择 Django、在开发过程中遇到的实际问题、以及如何一步步把它搭起来的过程。也许你也是刚入行或者打算进入 Python Web 开发领域的新手,希望这篇基于真实工作场景的经验分享能帮你在学习 Django 的路上少走一些弯路。


起因:为什么我要选 Django?

事情要回到上个月的一次需求评审会上。我们团队接到了一个任务——为公司内部搭建一个轻量级的员工信息管理平台(Intranet 工具),主要功能是:

  • 员工基本信息展示
  • 部门结构可视化
  • 快速查找和筛选
  • 可导出为 CSV 报表

这个平台的目标用户是公司内部人员,访问频率不算高,数据敏感性也不大,属于“够用就行”的类型。作为负责人,我需要快速交付一个原型,并且方便后续扩展。

考虑到时间和人力成本,我希望找一个既能快速开发、又能支撑一定规模应用的框架。PHP?太老了;Flask?虽灵活但很多轮子都得自己造;Node.js?当时刚好不在我的知识体系优先级里。于是我想起了之前略有耳闻的 Django —— 它内置了许多开箱即用的功能模块,比如 Admin 后台、ORM、模板系统、用户认证等等,非常适合这种中等规模的管理系统。

最终决定:试一试 Django!


实践第一步:初始化项目与目录结构规划

先来个热身环节吧,创建你的第一个 Django 项目。我一般习惯用虚拟环境隔离依赖,所以第一步就是:

python3 -m venv env
source env/bin/activate
pip install django
django-admin startproject employee_manager .

执行完之后会生成如下的基础目录结构:

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

接下来,我创建了一个 core 应用来组织核心业务逻辑:

python manage.py startapp core

并将其添加到 settings.py 中的 INSTALLED_APPS 列表里。

这时候我已经意识到一个潜在的问题:虽然 Django 提供了强大的 ORM 支持,但如果一开始就随意地定义模型,后期修改起来可能很麻烦。尤其是当数据库结构变动频繁的时候,迁移(Migration)操作如果不加注意,很容易出现数据丢失或混乱的情况。

所以我决定先梳理清楚业务模型之间的关系,再着手写 models。


数据库设计:简单却不能随便

这个系统的主要模型有三个:

  1. Employee(员工)
  2. Department(部门)
  3. Position(职位)

它们之间大致是这样的关系:

  • 一名员工只能属于一个部门,但每个部门可以有多名员工。
  • 每位员工有一个对应的职位,但一个职位可以被多个员工持有。
  • 部门可以嵌套父子关系(例如 IT 部下面分为前端组、后端组)。

于是我在 models.py 中设计如下模型结构(部分字段省略):

from django.db import models

class Department(models.Model):
    name = models.CharField(max_length=100)
    parent = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True)

    def __str__(self):
        return self.name

class Position(models.Model):
    title = models.CharField(max_length=100)

    def __str__(self):
        return self.title

class Employee(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    email = models.EmailField(unique=True)
    department = models.ForeignKey(Department, on_delete=models.CASCADE)
    position = models.ForeignKey(Position, on_delete=models.SET_NULL, null=True)


![负载均衡配置-1](https://code-guide.oss.shanghai.autogptai.club/common/file/download?name=date2025061719/6e465750-149b-4c51-953a-d2e84291a321.jpg)


    def __str__(self):
        return f"{self.first_name} {self.last_name}"

看起来挺简单对吧?但在实际开发中,我发现一个问题:如果我们直接用 Django 自带的 Admin 界面来管理这些数据,前端交互体验其实并不理想,特别是当你需要同时编辑多层嵌套的部门信息时。

怎么办呢?我选择了自定义 Admin 页面,并使用 TabularInline 来改善关联编辑体验:

# admin.py
from django.contrib import admin
from .models import Department, Employee, Position

class EmployeeInline(admin.TabularInline):
    model = Employee
    extra = 1

@admin.register(Department)
class DepartmentAdmin(admin.ModelAdmin):
    inlines = [EmployeeInline]

admin.site.register(Position)

这样就可以在一个页面上查看某个部门的所有员工了,效率提升了不少。


接口设计与性能优化:别忽视 RESTful 风格

除了后台管理,我还需要提供 API 接口给前端调用。因为后面可能会接入其他微服务系统,所以接口设计一定要规范、可拓展。

我使用的是 Django 自带的视图函数 + Django REST framework 插件。

安装 DRF:

pip install djangorestframework

然后在 urls.py 中配置路由,定义视图函数:

# views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Employee
from .serializers import EmployeeSerializer

@api_view(['GET'])
def get_employees(request):
    employees = Employee.objects.all()
    serializer = EmployeeSerializer(employees, many=True)
    return Response(serializer.data)

配合 serializers.py 定义序列化逻辑:

# serializers.py
from rest_framework import serializers
from .models import Employee

class EmployeeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Employee
        fields = '__all__'

但这里我遇到了一个小坑:随着数据量增加,全表查询变得缓慢。尤其是当员工数量超过 5000 条之后,GET /api/employees 接口响应时间明显延长。

分析发现:

  • 一次性返回所有员工会导致内存占用过高;
  • 查询未建立索引;
  • 大量字段未按需加载。

于是我对接口做了以下几项优化:

  1. 分页机制

引入分页器:

from rest_framework.pagination import PageNumberPagination

class StandardResultsSetPagination(PageNumberPagination):
    page_size = 20
    page_size_query_param = 'page_size'
    max_page_size = 100

@api_view(['GET'])
def get_employees(request):
    queryset = Employee.objects.all().select_related('department', 'position')
    paginator = StandardResultsSetPagination()
    result_page = paginator.paginate_queryset(queryset, request)
    serializer = EmployeeSerializer(result_page, many=True)
    return paginator.get_paginated_response(serializer.data)

这样既降低了单次请求的数据压力,也提升了接口稳定性。

  1. 数据库查询优化

通过 .select_related().prefetch_related() 减少 N+1 查询问题,并结合 Django Debug Toolbar 查看实际 SQL 执行情况。

  1. 建立索引

对于经常用于搜索的字段(如 emailfirst_name),在模型中指定数据库索引:

email = models.EmailField(unique=True, db_index=True)

这大大提高了 WHERE 查询的速度。


踩过的那些坑:生产部署中的真实教训

开发完成后,我开始着手部署。由于这是一个公司内网项目,我决定使用 Nginx + Gunicorn + PostgreSQL 搭建一个轻量级的部署环境。

第一次上线踩雷:“静态文件找不到”

在本地测试没问题,但部署到服务器后,CSS 和 JS 文件全都加载失败。

查日志发现:

  • Django 默认不会处理静态资源;
  • 使用 runserver 本地测试的时候,它自己会处理静态文件;
  • 一旦换到 Gunicorn+Nginx,必须手动配置静态资源路径。

解决方法:

  1. settings.py 中添加:

    STATIC_URL = '/static/'
    STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
    
  2. 运行收集命令:

    python manage.py collectstatic --noinput
    
  3. 在 Nginx 配置中设置:

    location /static/ {
        alias /path/to/staticfiles/;
    }
    

生产环境配置注意事项

  1. 关闭 DEBUG 模式:

    DEBUG = False
    ALLOWED_HOSTS = ['your.domain.com']
    

    不然线上报错信息全暴露出去,有安全风险。

  2. 正确设置 SECRET_KEY:

    不要提交到版本控制里。建议放在环境变量中读取:

    import os
    SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'fallback-secret-key-if-none')
    
  3. 使用 Gunicorn 启动服务:

    我常用的启动命令(带进程数):

    gunicorn --workers 3 employee_manager.wsgi:application
    
  4. 日志监控:

    部署后最好启用日志记录,方便追踪错误:

    LOGGING = {
        'version': 1,
        'handlers': {
            'file': {
                'level': 'DEBUG',
                'class': 'logging.FileHandler',
                'filename': '/path/to/debug.log',
            },
        },
        'loggers': {
            'django': {
                'handlers': ['file'],
                'level': 'DEBUG',
                'propagate': True,
            },
        },
    }
    

最终效果与个人心得

经过一周多的折腾,项目顺利上线,目前运行稳定,访问速度良好。前端同事反馈说接口清晰、文档完整,整体协作非常顺畅。

从这次实战中,我总结了几个实用经验:

  1. 先画模型,再写代码:

    • 模型的设计决定了数据的可维护性和扩展性;
    • 如果一开始没理清,后期改模型牵一发动全身。
  2. 不要小看分页的重要性:

    • 即使现在只有几百条数据,未来数据增长起来就会卡顿;
    • 分页 + 缓存能解决大多数性能瓶颈。
  3. 接口设计要规范:

    • 遵循 RESTful 标准,命名清晰;
    • 返回格式统一(状态码 + data + msg);
    • 尽早对接 Swagger 文档,提升协作效率。
  4. 调试工具是好伙伴:

    • Django Debug Toolbar;
    • Django extensions(如 shell_plus);
    • 测试驱动开发(TDD)也能帮助你写出更健壮的代码。
  5. 部署前做好准备:

    • 静态资源、权限、数据库连接都要检查;
    • 线上环境永远不要保留 DEBUG=True;
    • 日志是故障排查的第一线武器。

结语:别怕复杂,慢慢积累经验

说实话,第一次独立完成一个完整的 Django 项目并不是一件轻松的事,中间经历了各种调试、踩坑和重构。但正是这些看似琐碎的小事,让我逐步建立了对整个系统架构的理解,也让我对 Python Web 开发有了更深的兴趣。

如果你也是刚入门 Django,不用着急追求什么“完美架构”或“最佳实践”。先把项目跑起来,再去思考怎么做得更好,这才是最实在的成长方式。

最后送大家一句话:“慢一点没关系,坚持走下去才是关键。”

如果你在尝试的过程中遇到任何问题,欢迎留言交流!我们一起成长。

评论 0

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