You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用cookiecutter-django时应用外导入config模块及环境变量问题求助

问题:Cookiecutter-Django外部应用导入配置及环境变量读取失败

问题概述

使用Cookiecutter-Django框架开发时,遇到两个核心问题:

  • 在Django应用外部的bot/bot.py中尝试导入config模块,抛出ModuleNotFoundError: No module named 'config'
  • 若改用os.environ['BOT_TOKEN']读取环境变量,project/app/signals.py中会出现KeyError: 'BOT_TOKEN'

需求是实现:当Django模型对象创建时,通过Telegram Bot发送消息,BOT_TOKEN存储在.envs/.local/.bot文件中。

项目结构

project
 ┣ .envs
 ┃ ┗ .local
 ┃ ┃ ┣ .bot
 ┃ ┃ ┣ .django
 ┣ bot
 ┃ ┣ __init__.py
 ┃ ┗ bot.py
 ┣ compose
 ┃ ┣ local
 ┃ ┃ ┣ django
 ┃ ┃ ┃ ┣ Dockerfile
 ┃ ┃ ┃ ┗ start
 ┃ ┃ ┗ pytelegrambot
 ┃ ┃ ┃ ┣ Dockerfile
 ┃ ┃ ┃ ┗ start
 ┣ config
 ┃ ┣ settings
 ┃ ┃ ┣ __init__.py
 ┃ ┃ ┣ base.py
 ┃ ┃ ┣ local.py
 ┃ ┣ __init__.py
 ┃ ┣ urls.py
 ┃ ┗ wsgi.py
 ┣ project
 ┃ ┣ app
 ┃ ┃ ┣ migrations
 ┃ ┃ ┃ ┗ __init__.py
 ┃ ┃ ┣ admin.py
 ┃ ┃ ┣ apps.py
 ┃ ┃ ┣ signals.py
 ┃ ┃ ┣ models.py
 ┃ ┃ ┗ views.py
 ┣ requirements
 ┃ ┣ base.txt
 ┣ README.md
 ┣ local.yml
 ┣ manage.py

相关代码

bot.py

import telebot
from config.settings.base import env

bot = telebot.TeleBot(env('BOT_TOKEN'))

def send_welcome(message):
    print(message)

if __name__ == '__main__':
    bot.infinity_polling()

signals.py

from bot.bot import send_welcome

@receiver(post_save, sender=Model)
def translate(sender, instance, created, **kwargs):
    send_wlcome("Hi")  # 注意:此处函数名拼写错误,应为send_welcome

解决方案

1. 解决config模块导入问题

由于bot目录不在Python默认搜索路径中,需要将项目根目录添加到Python路径:

  • 在bot.py开头添加路径配置:
    import sys
    import os
    # 获取项目根目录(bot目录的父级目录)
    project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(project_root)
    
  • 或者运行bot时通过环境变量指定路径:
    PYTHONPATH=/path/to/project python bot/bot.py
    

2. 解决环境变量读取问题

Cookiecutter-Django使用python-dotenv加载环境变量文件,需让bot手动加载.envs/.local/.bot:

  • 在bot.py中添加环境变量加载逻辑:
    from dotenv import load_dotenv
    
    # 加载bot专属的环境变量文件
    env_file_path = os.path.join(project_root, '.envs', '.local', '.bot')
    load_dotenv(env_file_path)
    
  • 同时修正signals.py中的函数名错误:把send_wlcome改为send_welcome

3. 最优方案:复用Django环境

让bot初始化时加载Django运行环境,直接复用Django的配置和环境变量加载逻辑:

import os
import sys

# 添加项目根目录到Python路径
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(project_root)

# 设置Django配置模块并初始化
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")
import django
django.setup()

# 现在可以正常导入config模块和使用env
from config.settings.base import env
import telebot

bot = telebot.TeleBot(env('BOT_TOKEN'))

def send_welcome(message):
    print(message)

if __name__ == '__main__':
    bot.infinity_polling()

此方案下,signals.py在Django上下文运行时,环境变量已被自动加载,只需修正函数名拼写错误即可正常调用send_welcome。

内容的提问来源于stack exchange,提问作者mirodil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 08:01:56