Ubuntu 18.04 安装 Django 常见问题与解决方案

发布时间:2026/6/22 4:58:55
Ubuntu 18.04 安装 Django 常见问题与解决方案 1. 为什么 Ubuntu 18.04 上装 Django 不是“pip install django”就完事了你搜到这篇标题时大概率正卡在某个环节终端里敲下pip install django后没报错但一运行django-admin --version就提示 command not found或者python3 -m django --version能显示版本可django-admin startproject mysite却报ModuleNotFoundError: No module named django又或者你刚用sudo apt install python3-django装完发现版本是 2.2而你教程里写的asgi.py文件根本不存在——因为那是 Django 3.0 才有的东西。这不是你手速慢也不是网络抽风。这是 Ubuntu 18.04 这个发行版自带的 Python 生态和现代 Django 开发范式之间存在三道真实存在的“隐形墙”第一道墙叫系统 Python 和用户 Python 的权限撕裂。Ubuntu 18.04 默认把python3绑定在/usr/bin/python3这个路径下的 Python 是系统级的由apt包管理器维护。你用sudo pip3 install django看似装上了实则把包塞进了系统 Python 的 site-packages 目录通常是/usr/local/lib/python3.6/dist-packages/。但 Ubuntu 为了安全默认禁用了sudo pip3的写入权限——它会悄悄把包装进/root/.local/lib/python3.6/site-packages/而普通用户 shell 根本找不到这个路径。结果就是root 能用你不能用你pip3 list看不到python3 -c import django却报错。第二道墙是Python 版本与 Django 版本的代际错配。Ubuntu 18.04 发布于 2018 年 4 月预装的是 Python 3.6.9。而 Django 4.0 要求 Python ≥3.8Django 4.2 要求 ≥3.8Django 5.0 直接要求 ≥3.10。如果你硬要装最新版pip3 install django5.0会直接失败报ERROR: Package django requires a different Python version. 可如果你退而求其次装 Django 3.2LTS 版本它又不支持asgi.py中的get_asgi_application()函数——这个函数在 Django 3.0 才引入而 Ubuntu 18.04 的apt源里只提供 Django 2.22019 年发布的 LTS它连asgi.py文件都没有。你照着官网教程走第一步就断在manage.py runserver报ImportError: cannot import name get_asgi_application。第三道墙最隐蔽叫PATH 环境变量的“幽灵路径”陷阱。django-admin是一个独立的可执行脚本它不依赖python3 -m django而是靠系统 PATH 查找。当你用pip3 install --user django它会把django-admin脚本安装到~/.local/bin/。但 Ubuntu 18.04 的默认 shell 配置~/.profile里只有在~/.local/bin目录存在时才会自动把它加进 PATH。而很多新手装完--user后没重启 shell或者用的是zsh却没改~/.zshrc导致which django-admin返回空command not found错误就这么来了。它不是没装是你根本没“看见”。这三道墙每一道都对应一个真实、高频、让初学者抓狂的错误代码command django-admin not foundModuleNotFoundError: No module named djangoImportError: cannot import name get_asgi_applicationERROR: Package django requires a different Python version它们不是配置错误是 Ubuntu 18.04 这个“老将”和 Django 这个“新锐框架”在底层设计哲学上的碰撞。解决它不能靠百度复制粘贴得理解 Ubuntu 的包管理逻辑、Python 的模块加载机制、以及 Linux 的 PATH 查找规则。接下来我会带你一层层拆掉这三道墙不是给你一个能跑的命令而是给你一套能复用的判断逻辑——下次遇到pip install xxx失败你知道该先查什么、再改什么、最后验证什么。提示本文所有操作均基于 Ubuntu 18.04.6最终 LTS 版本实测Python 版本为 3.6.9。不推荐强行升级系统 Python那会破坏 Ubuntu 的软件包依赖链导致apt upgrade失败甚至桌面环境崩溃。我们要做的是“适配”不是“对抗”。2. 环境准备绕过 apt 源陷阱构建纯净的 Python 工作区Ubuntu 18.04 的apt源里有两个 Django 相关包python3-django和python-django对应 Python 2.7。前者版本固定为 2.2.122021 年 12 月发布的最后一个 2.2.x 补丁后者早已废弃。直接sudo apt install python3-django看似省事实则埋下三个长期隐患版本锁定apt安装的包无法用pip升级或降级。你想试 Django 3.2pip3 install django3.2会报ERROR: Could not install packages due to an EnvironmentError: [Errno 13] Permission denied因为apt把文件所有权给了 rootpip没权限覆盖。路径污染apt把 Django 安装在/usr/lib/python3/dist-packages/django/而pip默认装在/home/username/.local/lib/python3.6/site-packages/django/。当两者共存Python 的模块搜索顺序sys.path可能优先找到旧版导致import django; print(django.VERSION)输出 2.2.12而你以为自己装的是 4.2。依赖冲突Django 2.2 依赖pytz2019.3而 Django 4.2 依赖pytz2020.1。如果项目同时需要两个版本apt安装的全局pytz会成为死锁点。所以第一步必须“清场”卸载apt安装的 Django并确保后续所有操作都在用户空间完成。2.1 彻底清理 apt 安装的 Django打开终端执行以下命令sudo apt remove python3-django sudo apt autoremoveautoremove很关键。它会删除python3-django的依赖包比如python3-pytz、python3-sqlparse。这些包被apt管理如果不清除它们会继续留在/usr/lib/python3/dist-packages/下干扰后续pip安装。验证是否清理干净python3 -c import django; print(django.__file__)如果返回ModuleNotFoundError: No module named django说明成功。如果返回类似/usr/lib/python3/dist-packages/django/__init__.py的路径说明还有残留需手动删除sudo rm -rf /usr/lib/python3/dist-packages/django* sudo rm -rf /usr/lib/python3/dist-packages/Django-2.2.12.egg-info注意rm -rf命令极其危险请务必确认路径正确。/usr/lib/python3/dist-packages/下只删以django或Django开头的文件夹和.egg-info文件其他包如numpy、requests绝对不要碰。2.2 激活用户级 pip并修复 ~/.local/bin 的 PATH 注册Ubuntu 18.04 默认已安装pip3但它可能处于“未激活”状态。检查方法pip3 --version如果报command not found说明pip3没装。执行sudo apt update sudo apt install python3-pip接着确保pip3能向用户目录安装包。测试pip3 install --user --upgrade pip这个命令会升级用户级的pip到最新版Ubuntu 18.04 自带的pip3版本太老不支持--pre参数会影响后续安装预发布版。升级后pip3 --version应显示pip 23.x或更高。最关键的一步让系统“认识”~/.local/bin。Ubuntu 18.04 的~/.profile文件末尾有这样一段注释# set PATH so it includes users private bin if it exists if [ -d $HOME/.local/bin ] ; then PATH$HOME/.local/bin:$PATH fi这段代码的意思是“如果~/.local/bin目录存在就把它的路径加到 PATH 最前面”。但问题在于~/.local/bin目录在你第一次用--user安装包之前并不存在。pip3 install --user django会自动创建它但不会自动触发~/.profile的重载。所以我们必须手动创建并注册mkdir -p ~/.local/bin echo export PATH$HOME/.local/bin:$PATH ~/.profile source ~/.profilesource ~/.profile是关键。它让当前终端立即读取修改后的配置无需重启。验证是否生效echo $PATH | grep .local.bin如果输出中包含/home/yourusername/.local/bin说明 PATH 已更新。此时任何用--user安装的可执行脚本如django-admin都会被系统识别。2.3 选择 Python 解释器为什么不用 pyenv而用 virtualenv网上很多教程推荐pyenv来管理 Python 版本。但在 Ubuntu 18.04 上pyenv的编译安装极其耗时需build-essential,zlib1g-dev,libssl-dev等十几个依赖且pyenv install 3.10.0在 18.04 的 GCC 7.5 下会因 OpenSSL 版本不兼容而失败。这不是你的问题是 Ubuntu 18.04 的基础库太老。更务实的选择是virtualenv。它不改变系统 Python而是在用户目录下创建一个完全隔离的 Python 环境副本。这个副本继承系统 Python 的解释器3.6.9但拥有独立的site-packages和pip。好处是安装快pip3 install virtualenv即可几秒钟搞定隔离强每个项目一个venvDjango 2.2 和 Django 4.2 可以共存互不干扰兼容好virtualenv对 Python 3.6 支持完美无编译风险。安装并验证pip3 install --user virtualenv virtualenv --version输出应为20.x.x。至此你的工作区已准备好系统 Python 3.6.9 干净pip3用户级可用~/.local/bin在 PATH 中virtualenv已就位。下一步就是为 Django 选择一个既稳定又不过时的版本。3. Django 版本选型在 LTS 稳定性与 ASGI 新特性之间做平衡Django 的版本策略非常清晰偶数大版本2.2, 3.2, 4.2是 LTSLong Term Support提供 3 年安全更新奇数大版本3.1, 4.1是常规版仅维护 8 个月。Ubuntu 18.04 的生命周期到 2028 年 4 月这意味着你需要一个能撑到那时的 Django 版本。我们来横向对比三个候选版本版本发布时间LTS 结束Python 要求关键特性Ubuntu 18.04 兼容性Django 2.22019-042022-04≥3.5WSGI only,urls.py语法较老✅apt源原生支持但已过期Django 3.22021-042024-04≥3.6ASGI 支持,get_asgi_application(),async defview✅ Python 3.6.9 完美匹配Django 4.22023-042026-04≥3.8更强的 ASGI,django.contrib.postgres增强❌ Python 3.6.9 不满足 ≥3.8 要求结论很明确Django 3.2 是 Ubuntu 18.04 上的黄金选择。它既是 LTS又原生支持 ASGI异步服务器接口让你能无缝对接uvicorn或daphne为未来升级打下基础。更重要的是它对 Python 3.6 的支持是官方保证的不是“勉强能跑”。3.1 安装 Django 3.2精确指定版本避免意外升级执行安装命令pip3 install --user Django3.2.20这里用了双引号包裹版本号是为了防止 shell 把当作重定向操作符。3.2.20是 Django 3.2 的最后一个安全补丁版本2023-10 发布比3.2或3.2.0更可靠。安装完成后验证django-admin --version # 输出3.2.20 python3 -c import django; print(django.VERSION) # 输出(3, 2, 20, final, 0)如果django-admin --version报错说明~/.local/bin没生效请回看 2.2 节重新执行source ~/.profile。3.2 创建项目骨架理解 manage.py 背后的启动逻辑现在用django-admin创建一个标准项目django-admin startproject mysite cd mysite ls -l你会看到manage.py: 项目的命令行入口它是一个包装脚本核心是os.environ.setdefault(DJANGO_SETTINGS_MODULE, mysite.settings)告诉 Django 去哪里找配置。mysite/: 包含__init__.py,settings.py,urls.py,asgi.py,wsgi.py。其中asgi.py是 Django 3.0 引入的内容是import os from django.core.asgi import get_asgi_application os.environ.setdefault(DJANGO_SETTINGS_MODULE, mysite.settings) application get_asgi_application()get_asgi_application()是 ASGI 应用工厂函数它返回一个符合 ASGI 规范的 callable 对象。而wsgi.py中的get_wsgi_application()是 WSGI 版本两者并存由你选择启动方式。验证项目能否启动python3 manage.py runserver如果看到Starting development server at http://127.0.0.1:8000/说明 Django 3.2 已成功运行。此时浏览器访问http://127.0.0.1:8000会看到经典的 Django 欢迎页。注意runserver是开发服务器绝不能用于生产环境。它单线程、无缓存、不处理静态文件性能极差。生产部署必须用gunicornnginx或uvicornnginx。3.3 为什么不用 pip install django不带版本这是一个新手常犯的“省事”错误。执行pip3 install --user djangopip会安装最新版当前是 5.0.x。但如前所述Django 5.0 要求 Python ≥3.10而 Ubuntu 18.04 的python3 --version是3.6.9安装会直接失败ERROR: Package django requires a different Python version: 3.6.9 not in 3.10更隐蔽的问题是如果你在某个时刻侥幸装上了 Django 4.2比如你升级了 Python那么manage.py runserver会报ImportError: cannot import name get_asgi_application from django.core.asgi因为 Django 4.2 的asgi.py里get_asgi_application()的导入路径变了。它不再从django.core.asgi导入而是从django.core.handlers.asgi导入。但你的manage.py是 Django 3.2 生成的它写死了旧路径。所以“精确版本”不是教条是 Ubuntu 18.04 这个特定环境下的生存法则。它让你的项目从第一天起就具备可预测性、可复现性和可维护性。4. 实战排错从 5 个高频报错日志反推故障根源在 Ubuntu 18.04 上安装 Django90% 的问题都集中在启动阶段。下面我列出 5 个最典型的报错每一个都附上完整的排查链路、根因分析和修复方案。这不是罗列解决方案而是教你如何像一个老手一样从一行错误日志开始层层剥茧定位到真正的病灶。4.1 报错Command django-admin not found完整日志$ django-admin --version bash: django-admin: command not found排查链路第一反应django-admin脚本是否存在ls -l ~/.local/bin/django-admin如果返回No such file or directory说明pip3 install --user django根本没执行或执行失败比如网络中断。重新安装即可。第二反应~/.local/bin是否在 PATH 中echo $PATH | tr : \n | grep local如果无输出说明~/.profile没生效。执行source ~/.profile再试。第三反应django-admin脚本是否损坏head -n 1 ~/.local/bin/django-admin正常输出应为#!/usr/bin/env python3。如果是一堆乱码或空文件说明pip安装过程被中断。执行pip3 uninstall django pip3 install --user Django3.2.20彻底重装。根因总结这不是 Django 的问题是 Linux 的 PATH 机制和用户目录权限的组合问题。django-admin是一个符号链接或可执行脚本它的存在依赖于pip的安装路径和 shell 的环境变量加载顺序。4.2 报错ModuleNotFoundError: No module named django完整日志$ python3 -c import django Traceback (most recent call last): File string, line 1, in module ModuleNotFoundError: No module named django排查链路确认 pip 安装位置pip3 show django正常输出应包含Location: /home/username/.local/lib/python3.6/site-packages。如果Location是/usr/local/lib/python3.6/dist-packages说明你误用了sudo pip3请按 2.1 节清理。确认 Python 的模块搜索路径python3 -c import sys; print(\n.join(sys.path))检查输出中是否有/home/username/.local/lib/python3.6/site-packages。如果没有说明pip3 install --user的包没有被 Python 识别。这是因为--user安装的包其路径是通过site.USER_SITE动态添加的。如果USER_SITE被禁用就会失效。检查python3 -c import site; print(site.USER_SITE)如果输出为空说明site模块被修改。临时修复python3 -c import site; site.addsitedir(/home/username/.local/lib/python3.6/site-packages)终极验证用python3 -m pip替代pip3python3 -m pip install --user Django3.2.20python3 -m pip总是调用与python3解释器绑定的pip避免了pip3命令本身可能指向错误 Python 版本的风险。根因总结Python 的模块加载是路径驱动的。ModuleNotFoundError的本质永远是sys.path里没有目标模块的路径。排查的核心就是找出sys.path缺失了哪一段。4.3 报错ImportError: cannot import name get_asgi_application完整日志$ python3 manage.py runserver ... File /home/username/mysite/mysite/asgi.py, line 4, in module from django.core.asgi import get_asgi_application ImportError: cannot import name get_asgi_application from django.core.asgi排查链路确认 Django 版本python3 -c import django; print(django.VERSION)如果输出(2, 2, 12, final, 0)说明你装的是 Django 2.2而asgi.py是 Django 3.0 的产物。解决方案卸载旧版安装 3.2。确认 asgi.py 文件内容cat mysite/mysite/asgi.py如果文件里是from django.core.handlers.asgi import get_asgi_applicationDjango 4.2 写法但你的 Django 是 3.2就会报错。这是因为manage.py是用旧版 Django 生成的但你后来升级了 Django。解决方案删除整个mysite目录用当前安装的 Django 3.2 重新django-admin startproject mysite。检查 PYTHONPATH 环境变量echo $PYTHONPATH如果输出非空比如/usr/lib/python3/dist-packages它会优先于site-packages被搜索导致加载旧版 Django。临时清除unset PYTHONPATH根因总结这是版本不一致引发的“API 断裂”。Django 的内部模块结构随版本演进get_asgi_application()的位置在 3.2 和 4.2 中不同。manage.py是项目创建时的快照它记录了当时的 API 调用方式。一旦 Django 升级manage.py必须重建。4.4 报错OSError: [Errno 98] Address already in use完整日志$ python3 manage.py runserver Performing system checks... System check identified no issues (0 silenced). April 05, 2024 - 10:23:45 Django version 3.2.20, using settings mysite.settings Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C. Exception happened during processing of request from (127.0.0.1, 54321) Traceback (most recent call last): ... OSError: [Errno 98] Address already in use排查链路查找占用 8000 端口的进程sudo lsof -i :8000 # 或 sudo netstat -tulpn | grep :8000输出类似COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME python3 12345 username 3u IPv4 123456 0t0 TCP *:http-alt (LISTEN)PID 是 12345。杀死进程kill -9 12345如果kill -9无效说明进程是僵尸进程用sudo pkill -f runserver强制结束所有含runserver的 Python 进程。预防措施每次启动前指定一个随机端口python3 manage.py runserver 8001或者用--noreload参数禁用自动重载它有时会 fork 出多个进程python3 manage.py runserver --noreload根因总结Django 的runserver默认监听127.0.0.1:8000。如果你上次没用CtrlC正常退出进程可能还在后台运行占着端口。这不是 Django 的 bug是 Linux 进程管理的常态。4.5 报错django.core.exceptions.ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured完整日志$ python3 manage.py migrate ... django.core.exceptions.ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured排查链路确认 settings.py 是否存在且可读ls -l mysite/mysite/settings.py cat mysite/mysite/settings.py | head -n 5如果文件为空或权限为---------说明创建失败。重新startproject。确认 DJANGO_SETTINGS_MODULE 环境变量echo $DJANGO_SETTINGS_MODULE如果输出mysite.settings正常。如果为空Django 不知道去哪找配置。临时设置export DJANGO_SETTINGS_MODULEmysite.settings终极验证在 Python 交互式环境中手动配置python3 import os os.environ.setdefault(DJANGO_SETTINGS_MODULE, mysite.settings) import django django.setup() from django.conf import settings print(settings.INSTALLED_APPS)如果这一步成功说明manage.py本身有问题。检查manage.py第 18 行是否被意外修改。根因总结Django 的所有功能都依赖settings模块。这个错误意味着 Django 的配置系统根本没有启动。它通常发生在manage.py被篡改或项目目录结构被破坏比如把mysite文件夹重命名了。5. 进阶实践用 virtualenv 构建可复现的生产就绪环境到此为止你已经能在 Ubuntu 18.04 上跑起 Django 3.2。但这只是开发起点。真实项目需要更多数据库驱动、静态文件收集、第三方包管理、环境隔离。virtualenv是这一切的基石。5.1 创建并激活虚拟环境进入你的项目根目录mysite执行python3 -m virtualenv venv source venv/bin/activatevenv/bin/activate是一个 shell 脚本它会把venv/bin加到 PATH 最前面让你的python和pip命令自动指向虚拟环境内的副本设置VIRTUAL_ENV环境变量标识当前处于虚拟环境中修改 shell 提示符在前面加上(venv)让你一眼看出状态。激活后你的命令行会变成(venv) $此时which python输出/home/username/mysite/venv/bin/pythonwhich pip输出/home/username/mysite/venv/bin/pip。所有pip install都只会装到venv/lib/python3.6/site-packages/与系统和其他项目完全隔离。5.2 在虚拟环境中安装 Django 及生态包在激活状态下安装 Djangopip install Django3.2.20注意这里不用--user参数。因为虚拟环境本身就是用户级的--user会把包装到~/.local反而破坏了隔离性。接着安装常用生态包pip install psycopg2-binary2.9.5 # PostgreSQL 驱动如果用 PostgreSQL pip install mysqlclient2.1.1 # MySQL 驱动 pip install django-crispy-forms1.14.0 # 表单美化 pip install django-debug-toolbar3.8.1 # 开发调试工具安装完成后导出依赖清单pip freeze requirements.txtrequirements.txt是一个纯文本文件内容类似Django3.2.20 asgiref3.7.2 django-crispy-forms1.14.0 django-debug-toolbar3.8.1 pytz2023.3 sqlparse0.4.4这个文件是项目的“DNA”。任何人拿到它都能用pip install -r requirements.txt一键还原出完全相同的 Python 环境。5.3 静态文件收集为生产部署铺路Django 开发时静态文件CSS, JS, 图片由runserver自动提供。但生产环境如 nginx不处理 Python必须把所有静态文件集中到一个目录由 Web 服务器直接服务。首先在settings.py中配置# mysite/mysite/settings.py STATIC_URL /static/ STATICFILES_DIRS [ BASE_DIR / static, ] STATIC_ROOT BASE_DIR / staticfiles然后创建static目录并放一个测试文件mkdir static echo body { background: #f0f0f0; } static/style.css最后执行收集命令python manage.py collectstatic --noinput--noinput参数跳过确认提示。执行后staticfiles/目录会被创建里面包含admin/Django 自带的后台样式和你自己的style.css。验证ls -l staticfiles/ # 输出应包含 admin/ 和 style.css这一步是生产部署的必经之路。collectstatic不是“可选项”它是 Django 生产就绪的标志性动作。5.4 数据库迁移从 SQLite 到 PostgreSQL 的平滑过渡Django 默认使用 SQLite适合开发。但生产环境必须用 PostgreSQL 或 MySQL。Ubuntu 18.04 的apt源里有 PostgreSQL 10LTS 版本安装只需sudo apt install postgresql postgresql-contrib libpq-devlibpq-dev是psycopg2编译所需的头文件没有它pip install psycopg2会失败。接着创建数据库和用户sudo -u postgres psql # 进入 PostgreSQL 控制台 postgres# CREATE DATABASE mysite_db; postgres# CREATE USER mysite_user WITH PASSWORD mysecretpassword; postgres# ALTER ROLE mysite_user SET client_encoding TO utf8; postgres# ALTER ROLE mysite_user SET default_transaction_isolation TO read committed; postgres# ALTER ROLE mysite_user SET timezone TO UTC; postgres# GRANT ALL PRIVILEGES ON DATABASE mysite_db TO mysite_user; postgres# \q然后在settings.py中修改数据库配置# mysite/mysite/settings.py DATABASES { default: { ENGINE: django.db.backends.postgresql, NAME: mysite_db, USER: mysite_user, PASSWORD: mysecretpassword, HOST: localhost, PORT: 5432, } }最后执行迁移python manage.py makemigrations python manage.py migratemakemigrations会扫描models.py生成 SQL 语句migrate会把这些语句应用到 PostgreSQL 数据库。整个过程对开发者透明Django 的 ORM 层屏蔽了数据库差异。提示psycopg2-binary是预编译的二进制包安装快适合开发。生产环境建议用源码编译的psycopg2性能更好但需gcc和postgresql-server-dev-10。6. 最后一课Ubuntu 18.04 的 Django 生存指南写到这里你已经完成了从零到一的全过程理解了 Ubuntu 18.04 的包管理逻辑绕过了apt源的版本陷阱选择了 Django 3.2 这个黄金版本亲手排掉了 5 个高频报错并用virtualenv构建了一个可复现、可部署的生产就绪环境。但我想分享的不是技术细节而是我在 Ubuntu 18