尧图精选

Django全栈开发实战:环境配置、ORM操作与部署上线

🕒 发布时间:2026/10/2 2:51:44 📁 来源:尧图网络
1. 从零搭好Django开发环境虚拟环境、版本选择与pip镜像源很多新手学Django第一关不是语法而是环境。我刚接触时直接在系统Python里pip install django结果没过多久就乱了——今天装这个库明天那个项目要不同版本系统Python环境被搞得一塌糊涂。后来才明白Django项目必须建在独立的虚拟环境里这一步省掉后面全是坑。1.1 先选Python版本再选Django版本先聊聊版本这件事。Django的版本节奏挺快长期支持版LTS和非长期支持版交替发布。我的建议很直接如果你是新手或者要上生产环境就选当前最新的LTS版本比如Django 4.2系列或5.x的LTSPython版本用3.10以上即可。不要追最新版本因为它可能还有兼容性问题很多第三方库还没来得及跟上。怎么确认对应关系直接看Django官方文档的版本兼容表里面写得很清楚Django 4.2支持Python 3.8到3.12Django 5.x支持Python 3.10以上。这里有个经验Python版本尽量用官方下载页的稳定版别用奇怪的发行版否则后面装依赖库时容易遇到编译错误。1.2 虚拟环境创建实操Windows和macOS/Linux的创建命令有一点点区别但思路一样# 创建虚拟环境venv是Python自带的不需要额外装 python -m venv django_env # 激活虚拟环境 # Windows django_env\Scripts\activate # macOS/Linux source django_env/bin/activate激活成功后命令行前面会出现(django_env)的标识这就是进入虚拟环境的信号。之后所有的pip install和python命令都会在这个隔离环境里运行不会污染系统的Python。1.3 pip配置国内镜像源为什么必须做这一步这一步经常被忽略但实际影响巨大。默认的pip源在国外下载速度很慢还容易超时尤其是一些体积大的依赖包比如Pillow、psycopg2这些卡个十分钟很正常。我是直接把pip源换成国内镜像一劳永逸# 在用户目录下创建pip配置文件 # Windows路径C:\Users\你的用户名\pip\pip.ini # macOS/Linux路径~/.config/pip/pip.conf [global] index-url https://pypi.tuna.tsinghua.edu.cn/simple trusted-host pypi.tuna.tsinghua.edu.cn timeout 120换完源之后装Django的速度简直是天壤之别。实测下来清华源的速度稳定在几MB/s基本是秒装。1.4 安装Django并验证pip install django装完验证一下python -m django --version如果正常输出版本号说明安装成功。这里有个细节建议用python -m django而不是直接敲django-admin因为有时候系统里存在多个Python版本直接敲命令可能调用到错误的环境而python -m django能保证用的是当前虚拟环境里的那一套。还有一个小建议顺手把pip升级到最新版pip install --upgrade pip新版pip对依赖解析更合理安装过程中不容易出现依赖冲突这类烦人的问题。2. 创建项目与第一个页面把Hello World跑起来的完整链路环境搞定之后真正进入项目环节。Django的项目结构是两个层级项目project和应用app。项目是整个网站的配置和入口应用是具体的功能模块。先创建项目再往里加应用。2.1 项目初始化命令详解django-admin startproject myblog这条命令会创建一个myblog目录里面自动生成以下结构myblog/ ├── manage.py # 项目管理入口所有命令都通过它执行 └── myblog/ ├── __init__.py ├── settings.py # 全站配置文件 ├── urls.py # 根URL路由 ├── asgi.py # 异步网关接口 └── wsgi.py # 同步网关接口很多人不明白manage.py是干什么的我打个比方它就像一个遥控器启动服务器、创建应用、跑数据库迁移全靠它。后面你会反复用到python manage.py开头的命令。2.2 启动开发服务器验证环境cd myblog python manage.py runserver看到Starting development server at http://127.0.0.1:8000/这样的输出就说明项目跑起来了。浏览器访问这个地址如果出现一个火箭图标并显示It worked!恭喜你的Django项目已经能运行了。这里说两个新手容易困惑的点第一开发服务器为什么是8000端口因为8000是Django默认的开发端口如果被占用可以指定端口python manage.py runserver 8080第二开发服务器能用于生产环境吗绝对不能。它是一个轻量级的服务是为了开发调试方便性能和安全防护都不够。生产环境需要用Gunicorn或者uWSGI来跑Django后面会讲到。2.3 配置ALLOWED_HOSTS频繁踩坑的重要设置在settings.py里有个ALLOWED_HOSTS配置默认是空的列表。如果设置不对访问时会报DisallowedHost错误。开发阶段怎么配ALLOWED_HOSTS [127.0.0.1, localhost]如果要让局域网内的手机或别的电脑访问你的开发服务器可以加上本机的局域网IPALLOWED_HOSTS [127.0.0.1, localhost, 192.168.1.100]这个配置在开发阶段不显眼到部署上线时就是个关键项域名要加进去不然会报错。我现在写项目第一步就把这个配好别等出错了再回来找。2.4 第一个视图理解URL路由的工作机制Django处理请求的方式可以概括为三步URL找到视图、视图处理逻辑、视图返回响应。先写一个最简视图在myblog/urls.py同级的目录下新建一个views.py文件初始项目里可能没有这个文件如果不存在就自己新建from django.http import HttpResponse def index(request): return HttpResponse(欢迎来到我的第一个Django页面)然后在myblog/urls.py里配置路由from django.contrib import admin from django.urls import path from . import views urlpatterns [ path(admin/, admin.site.urls), path(, views.index, nameindex), ]保存后刷新浏览器就能看到页面上显示欢迎来到我的第一个Django页面。虽然很简陋但整个链路已经通了请求进来 - 路由匹配 - 视图响应。到这一步你已经掌握了Django最基本的运作逻辑。接下来就是把这个简单的骨架丰富成一个有实际功能的应用。3. settings.py与数据库配置新手最容易忽略的几个坑settings.py是整个Django项目的枢纽几乎所有的全局配置都在这一个文件里。很多新手对它只有一个看到需要改就改的模糊认知其实每一组配置背后都有明确的逻辑。3.1 中文和时区不配置就会踩时间的坑INSTALLED_APPS和MIDDLEWARE我建议先保持默认新手阶段不要动它们。但有两项必须立刻改否则后面项目一跑就容易出问题就是语言和时区LANGUAGE_CODE zh-hans TIME_ZONE Asia/Shanghai默认是en-us和UTC不改成zh-hans和Asia/Shanghai的话Django自带的admin后台会显示英文而且数据库里存的时间比北京时间慢8个小时。这个坑我踩过很多次——尤其是后面做的功能里如果需要记录用户操作时间不配时区存进去的时间总是错的。注意如果你用了MySQL之类的数据库数据库连接字符串里也要把时区设为Asia/Shanghai两边对齐才不会出问题。3.2 数据库配置从SQLite切换到MySQL的完整步骤Django默认用的是SQLite这对学习和小项目完全够用零配置、文件型数据库省心。但如果你打算做正式项目或者需要更高的并发能力建议切换到MySQL或PostgreSQL。这里以MySQL为例。先在虚拟环境中装驱动pip install pymysql然后在myblog/__init__.py里加一行import pymysql pymysql.install_as_MySQLdb()再修改settings.pyDATABASES { default: { ENGINE: django.db.backends.mysql, NAME: myblog, USER: root, PASSWORD: 你的密码, HOST: 127.0.0.1, PORT: 3306, } }这里有个高频报错点字符集。MySQL默认的字符集在某些情况下是latin1存中文会乱码或报错。建议在数据库连接配置里加上OPTIONS: { charset: utf8mb4, },utf8mb4是完整版的UTF-8能支持emoji表情存中文毫无压力。3.3 STATIC_ROOT与MEDIA_ROOT文件管理的基本盘静态文件和上传文件是Web项目的常态需求Django对这两类文件有明确区分静态文件CSS、JS、图片属于项目自身的资源由STATICFILES_DIRS指定开发时的目录STATIC_ROOT指定部署后收集资源的目录。媒体文件用户上传的图片、附件由MEDIA_ROOT和MEDIA_URL管理。开发阶段的简单配置import os STATIC_URL /static/ STATICFILES_DIRS [os.path.join(BASE_DIR, static)] STATIC_ROOT os.path.join(BASE_DIR, collect_static) MEDIA_URL /media/ MEDIA_ROOT os.path.join(BASE_DIR, media)我刚开始学的时候没认真区分这几个参数结果在部署时发现静态文件找不到页面纯文字完全没样式排查了很久。后来形成习惯项目创建好之后第一时间把static和media目录建好配置写完整后面就不会乱。3.4 迁移命令数据库初始化的标准操作配置好数据库之后需要执行迁移命令Django会按照INSTALLED_APPS里默认应用的数据模型在数据库里自动创建对应的表python manage.py makemigrations python manage.py migratemakemigrations是生成迁移文件migrate是执行迁移。第一次跑完数据库里会出现一堆django_开头的表这是Django自带的用户、权限、会话等功能的表。看到这些表说明数据库连接成功了。提示每次修改了models.py都要重新执行这两条命令数据库表结构才会更新。这是Django的ORM体系正常工作的重要路径。4. 创建app与数据模型从ORM设计到admin后台项目只是一个壳真正的功能都写在app里。app你可以理解成一个个独立的功能模块——比如一个博客项目可以有文章app、评论app、用户app。每个app负责自己那一摊事。4.1 startapp创建一个文章应用python manage.py startapp article这会在项目根目录生成一个article目录里面自动包含models.py、views.py、admin.py、migrations/等文件。注意这个app创建好后要注册到settings.py里才生效INSTALLED_APPS [ django.contrib.admin, django.contrib.auth, django.contrib.contenttypes, django.contrib.sessions, django.contrib.messages, django.contrib.staticfiles, article, # 加上这一行 ]为什么需要注册因为Django启动时会扫描INSTALLED_APPS里每个应用的路由、模板、迁移文件等资源。不注册的话app的路由和模型都不会被加载访问就404。4.2 编写数据模型定义文章表在article/models.py里定义一个最简单的文章模型from django.db import models from django.contrib.auth.models import User class Article(models.Model): title models.CharField(max_length100, verbose_name标题) content models.TextField(verbose_name正文) author models.ForeignKey(User, on_deletemodels.CASCADE, verbose_name作者) created_time models.DateTimeField(auto_now_addTrue, verbose_name创建时间) updated_time models.DateTimeField(auto_nowTrue, verbose_name更新时间) class Meta: ordering [-created_time] verbose_name 文章 verbose_name_plural verbose_name def __str__(self): return self.title这里说一下ORM的基本概念。每一行都对应数据库表里的一列比如title models.CharField(max_length100)就是数据库里一个varchar(100)字段。ForeignKey表示外键关联这里关联到Django自带的User表一篇文章对应一个作者一个用户可以有多篇文章。on_deletemodels.CASCADE指定用户被删除时他的文章一并删除——这个参数必须显式指定否则Django会报错提示你补上。auto_now_add和auto_now的区别经常有人搞混auto_now_add是记录第一次创建时间创建后不再变动auto_now是每次保存都要更新时间。4.3 生成并执行迁移让表真正落地写完模型后执行一次迁移python manage.py makemigrations article python manage.py migrate想确认生成的SQL语句长什么样可以用python manage.py sqlmigrate article 0001这会打印出Django帮你自动生成的CREATE TABLE语句。刚开始学的时候看一眼这个输出能帮你把ORM和真实SQL对应起来理解会更扎实。4.4 注册到admin后台零代码管理数据Django自带的后台管理是它的加分项注册一下模型就能在后台直接增删改查数据。打开article/admin.pyfrom django.contrib import admin from .models import Article admin.register(Article) class ArticleAdmin(admin.ModelAdmin): list_display (title, author, created_time) search_fields (title, content)然后创建一个管理员账号python manage.py createsuperuser按提示输入用户名、邮箱、密码。启动服务器访问http://127.0.0.1:8000/admin/登录后就能看到文章管理界面。这是Django对开发效率的提升最直观的一个点——不需要手动写任何后台代码就拥有了一套完整的内容管理系统。在实际项目中我习惯在list_display里把常用字段都列出来比如标题、作者、时间方便后台审核内容时一目了然。5. 模板系统与静态文件把页面做得像样一点后端的数据模型已经通了接下来要把数据展示给用户。Django用的是自家的模板系统它的核心逻辑是模板负责页面结构视图负责传数据二者通过上下文变量连接。5.1 视图传数据到模板的基本方式在article/views.py里写一个视图把文章列表传给模板from django.shortcuts import render from .models import Article def article_list(request): articles Article.objects.all() return render(request, article/list.html, {articles: articles})render函数做了三件事加载模板文件、传入上下文变量、返回渲染后的HTTP响应。注意article_list这个名字对应的URL路由在项目根路由myblog/urls.py里配置from django.urls import path, include urlpatterns [ path(admin/, admin.site.urls), path(article/, include(article.urls)), ]然后在article/目录下新建urls.pyfrom django.urls import path from . import views urlpatterns [ path(, views.article_list, namearticle_list), ]这样访问/article/就能触发article_list视图。5.2 创建模板文件并渲染数据在article应用下新建templates/article/目录创建list.html!DOCTYPE html html head meta charsetutf-8 title文章列表/title /head body h1文章列表/h1 {% for article in articles %} div h2{{ article.title }}/h2 p{{ article.content | truncatechars:100 }}/p p作者{{ article.author.username }} | 发布时间{{ article.created_time }}/p /div {% empty %} p还没有文章快去后台添加吧。/p {% endfor %} /body /html模板语法里{% for %}是循环标签{{ article.title }}是变量输出。truncatechars:100是个好用的过滤器截断长文本列表页展示摘要时特别常用。5.3 静态文件加载CSS和JS的正确姿势页面光秃秃的不像话需要加样式。在项目根目录创建static/css/目录放一个简单的CSS文件然后在模板顶部引入{% load static %} !DOCTYPE html html head meta charsetutf-8 title文章列表/title link relstylesheet href{% static css/style.css %} /head这里{% load static %}必须写在模板开头它告诉Django这个模板要用到静态文件相关的模板标签。{% static css/style.css %}会在渲染时拼上你在settings.py里配置的STATIC_URL生成类似/static/css/style.css的完整路径。5.4 模板继承避免大量重复代码随着页面增多如果每个页面都复制一份完整的HTML骨架代码会非常冗余。Django的模板继承机制就是专门解决这个问题的。创建一个基础模板templates/base.html!-- templates/base.html -- {% load static %} !DOCTYPE html html head meta charsetutf-8 title{% block title %}我的网站{% endblock %}/title link relstylesheet href{% static css/style.css %} /head body nav a href/首页/a a href/article/文章列表/a /nav main {% block content %} {% endblock %} /main /body /html然后子模板只需要写属于自己的部分!-- article/templates/article/list.html -- {% extends base.html %} {% block title %}文章列表{% endblock %} {% block content %} {% for article in articles %} div h2{{ article.title }}/h2 p{{ article.content | truncatechars:100 }}/p /div {% endfor %} {% endblock %}{% extends %}是继承标记{% block %}是子模板要填充的区块。这种做法的好处是改导航栏、改页脚只需要动base.html一个文件所有页面同步生效。6. 表单、CSRF与Cookie/Token让用户和系统产生交互静态页面读起来没意思真正的Web应用必须支持用户输入。表单处理是Django的强项但也是新手最容易碰壁的地方——尤其是CSRF这个机制第一次遇到会用CSRF verification failed直接把人搞懵。6.1 一个简单但完整的表单流程先做一个发布文章的页面。在article/views.py里加一个视图from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from .models import Article login_required def create_article(request): if request.method POST: title request.POST.get(title) content request.POST.get(content) if title and content: Article.objects.create( titletitle, contentcontent, authorrequest.user, ) return redirect(article_list) return render(request, article/create.html)在article/urls.py里注册路由path(create/, views.create_article, namecreate_article),模板article/create.html{% extends base.html %} {% block content %} h1发布文章/h1 form methodpost {% csrf_token %} input typetext nametitle placeholder标题 required textarea namecontent placeholder正文 required/textarea button typesubmit发布/button /form {% endblock %}6.2 CSRF机制为什么模板里必须加那一行{% csrf_token %}这行简直是新手重灾区。有时候从网上复制代码忘了带它提交表单就报错。它的本质是一个安全令牌Django会在生成表单页面时在渲染的HTML里埋入一个一次性token提交时后端校验这个token。如果token不匹配就拒绝请求。这套机制能有效防止CSRF攻击——第三方网站伪造表单提交到你的站点。实际开发中如果你用Django的render渲染表单模板{% csrf_token %}是必须的。如果是前后端分离或者对接第三方API则需要配合Cookie里的CSRF token和请求头里的X-CSRFToken字段来通过验证。这块逻辑在Django文档里有专门章节值得深入读一遍。6.3 Cookie与Token的简单实践Django的会话系统默认将session数据存在数据库里通过Cookie中的sessionid来标识用户身份。登录后Django会自动设置这个Cookie后续请求带着它后端就能识别出这是哪个用户。那Token呢在前后端分离或需要给第三方提供API时光靠session就不够灵活了。Django官方推荐使用django-rest-framework的TokenAuthentication机制它为用户生成一个token字符串客户端在请求头里带上Authorization: Token 9944b09199c62bcf9418ad85ddd8bdf服务端校验这个token就能确定用户身份。Token的好处是不依赖Cookie跨域请求也好使方便移动端和第三方接入。提示如果你需要在Cookie里手动设置自定义token可以用Django的set_cookie方法但要设置合理的过期时间并用HttpOnly属性防止脚本读取降低安全风险。6.4 实际项目中的请求处理逻辑综合来说一个正常的表单处理流程是这样的用户访问表单页面请求方式是GET视图渲染表单模板并返回。用户填写并提交请求方式是POST视图根据提交的数据进行处理。数据校验后要么保存并重定向到成功页面要么返回错误信息并重新渲染表单。login_required会拦截未登录用户的访问自动跳转到登录页这是Django最常用的权限控制手段之一。我在实际项目里习惯把表单的数据校验写在forms.py里而不是直接在视图里手动判断。Django的Form表单类自带字段类型校验、错误提示、渲染等功能代码会比手写POST处理更规范也更安全。7. 从数据库查询到数据删除ORM的核心操作技巧前面我们已经在视图中用到了Article.objects.create()和Article.objects.all()这里把ORM的增删改查完整梳理一遍。这套操作是Django后端日常开发最常用的技能热搜里django执行查询-删除对象指的就是这一块。7.1 新增数据的几种姿势# 方式一create方法 article Article.objects.create(title标题, content内容, authoruser) # 方式二先实例化再save article Article(title标题, content内容, authoruser) article.save()两种方式效果基本一样区别在于create封装了创建和保存两步代码更简洁。需要处理额外逻辑时用先实例化再save的方式更灵活。7.2 查询数据复现日常开发最常用的查询条件# 获取全部数据 articles Article.objects.all() # 过滤标题包含某关键词 articles Article.objects.filter(title__icontainsdjango) # 单个对象 article Article.objects.get(id1) # 排序 articles Article.objects.order_by(-created_time) # 限制数量 articles Article.objects.all()[:5] # 统计数量 count Article.objects.count()filter返回的是一个QuerySet集合它支持链式调用可以不断叠加过滤条件。这里要注意一个高发坑get返回的是单个对象如果查询结果不存在或有多条都会抛出异常。不确定是否存在的时候用filter(...).first()更安全没有匹配时返回None不会中断程序。7.3 更新数据# 方式一实例操作 article Article.objects.get(id1) article.title 新标题 article.save() # 方式二批量更新 Article.objects.filter(authoruser).update(title统一标题)批量更新update就是一条UPDATE语句性能比一条条循环快得多。但注意批量更新不会触发模型里的save()方法所以auto_now字段在批量更新时不会自动更新Django 4.2以上的版本已支持update中显式处理这个参数具体看版本文档。吃不准的时候先查文档。7.4 删除对象delete()方法的关键细节删除是一个不可逆的操作Django给了两种方式# 删除单个对象 article Article.objects.get(id1) article.delete() # 批量删除 Article.objects.filter(created_time__year__lt2020).delete()删除操作有一个容易踩的点如果模型之间存在外键关联并且on_delete设置为CASCADE删除主记录时关联的子记录也会一起被删除。比如你的评论模型外键关联Article删掉文章会连带删掉它的所有评论。如果你希望删除文章时保留评论要么把on_delete改为SET_NULL子记录的外键字段允许为空要么在业务逻辑里提前处理这些关联数据。另外delete()方法返回的是一个(总数, 每个类型删除数量)的元组这在确认删除范围时很有用result Article.objects.filter(id1).delete() print(result) # (1, {article.Article: 1})7.5 F表达式处理并发场景下的字段更新如果说前面的操作还比较基础那F表达式就是进阶级的技巧。先看一个场景文章点击量加一。最直观的写法是article Article.objects.get(id1) article.pv 1 article.save()但这个写法在并发情况下有问题两个请求同时读到PV100各自加1再写回最终结果可能是101而不是102。用F表达式就能把一个数据库操作里完成字段自增from django.db.models import F Article.objects.filter(id1).update(pvF(pv) 1)F(pv)表示引用数据库里这一列的当前值这个操作是在数据库层面原子执行的不会出现并发竞争问题。做计数器、库存、点赞数这类功能时务必用F表达式。这是很多从数据库入门就开始用Django过程中才逐渐理解的关键点。8. WebSocket扩展与部署思路上线前最后那几步一个Django项目做到能增删改查、有后台、有页面基本就是个完整的Web应用了。但如果你的项目需要实时推送——比如热搜词里提到的python django websocket实现后台有数据前端推送——那就需要更进一步的技术栈。8.1 Django对WebSocket的支持方式Django是一个同步框架请求-响应模式处理得很好但WebSocket是长连接、双向通信Django原生没有直接支持。目前主流方案是Channels它让Django具备了异步处理能力。pip install channels然后在settings.py里把daphne和channels加入INSTALLED_APPS并配置ASGIINSTALLED_APPS [ daphne, channels, ... ] ASGI_APPLICATION myblog.asgi.application再配置一个简单的通道层CHANNEL_LAYERS { default: { BACKEND: channels.layers.InMemoryChannelLayer, }, }InMemoryChannelLayer是内存通道层只适合开发调试生产环境建议用Redis作为通道层后端支持跨进程通信。后台推送的基本思路是前端通过WebSocket连接到Django的ConsumerConsumer收到消息后把数据推送到前端页面。例如开发一个通知功能后台某个事件触发时通过channel_layer.group_send把消息推给所有订阅了某个频道的前端。我做过一个简单的实时日志查看器就是用Channels把Django后台的日志流推送到浏览器页面效果非常直观。但要提醒的是Channels的异步特性对Django开发者来说需要适应回调式的写法跟传统的同步视图区别很大第一次接触时建议从官方教程的聊天室Demo入手把Consumer和事件循环的机制跑通再说。8.2 部署前必须检查的清单开发环境的服务器不能直接用于生产上线前有几件事必须处理关闭调试模式DEBUG False这会导致错误页面不再显示详情避免敏感信息泄露。处理静态文件和媒体文件Django不擅长服务静态文件生产中要交给Nginx处理或用WhiteNoise这类中间件。所以前面我让你把STATIC_ROOT配好就是为此做的准备。配置数据库生产环境不要再用SQLite建议MySQL或PostgreSQL并做定期备份。设置环境变量数据库密码、Secret Key等敏感信息不要直接写死在settings.py用环境变量或配置文件外部管理。使用Gunicorn/uWSGI多进程运行Django应用gunicorn myblog.wsgi:application这条命令要反复跑。8.3 我的部署心得我个人在实际部署时比较常用Gunicorn Nginx MySQL这套组合。Nginx负责挡住外部流量、处理静态文件Gunicorn跑Django的Python进程MySQL存数据。域名配置好之后在ALLOWED_HOSTS里加上自己的域名用HTTPS证书把流量加密这才算一个合格的生产环境。部署过程中最容易翻车的是静态文件。开发时STATICFILES_DIRS指向的是源目录部署时要用python manage.py collectstatic把所有静态文件集中收集到STATIC_ROOT再让Nginx指向这个目录。我多次遇到部署后页面完全没有样式的问题九成是这一步没处理。9. 一些接近实战的补充建议文章写到最后分享几个我在Django实战中沉淀下来的小习惯。这些不是哪本教材里能找到的纯属踩坑踩出来的经验。第一目录结构不要图省事。很多人把所有app的models都塞在一个文件里项目小的时候无所谓项目一大就乱了。我建议一个app尽量保持一个清晰的功能边界比如用户、文章、评论、分类各管各的。Django的哲学是可复用app你以后会在多个项目之间复用代码边界清晰才能复用。第二及时做数据库备份和迁移文件的维护。每次makemigrations生成的迁移文件建议及时提交到版本控制里它们是数据库结构的变更记录换机器、上线、回滚都要靠这些文件。第三善用Django的日志功能。在生产环境里日志是诊断问题的第一手段。settings.py里用LOGGING配置一个文件日志把Django请求、SQL执行、错误堆栈都记录下来排查问题会轻松很多。第四坚持看官方文档。Django的文档质量在Web框架里算是顶级从入门到进阶每个概念都有详细解释。遇到不懂的先查官方文档再百度/谷歌能少走很多弯路。对于刚开始学Django的朋友我的建议是走完一个完整的闭环创建项目 - 建app - 定义模型 - 写视图和模板 - 加表单 - 部署上线。哪怕做一个极简的博客系统只要把这个闭环走完你对Django的理解就能超过很多人。下一步再往深走比如REST API、异步任务、缓存、消息队列都是在这个基础上扩展的。先把地基打牢比啥都重要。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →