Django管理命令导入config.ini时出现KeyError: 'Auth'问题
解决Django管理命令读取config.ini时的KeyError问题
问题情况
项目结构如下:
members ├── management │ ├── __init__.py │ ├── commands │ │ ├── active.py │ │ ├── whatsapp.py │ │ ├── config.ini
运行python manage.py active时触发KeyError:
C:\Users\timmeh\source\Python Projects\Django Projects\env\myproject\topxgym>python manage.py active Traceback (most recent call last): File "C:\Users\timmeh\source\Python Projects\Django Projects\env\myproject\topxgym\manage.py", line 22, in <module> main() File "C:\Users\timmeh\source\Python Projects\Django Projects\env\myproject\topxgym\manage.py", line 18, in main execute_from_command_line(sys.argv) File "C:\Users\timmeh\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\management\__init__.py", line 446, in execute_from_command_line utility.execute() File "C:\Users\timmeh\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\management\__init__.py", line 440, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "C:\Users\timmeh\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\management\base.py", line 402, in run_from_argv self.execute(*args, **cmd_options) File "C:\Users\timmeh\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\management\base.py", line 448, in execute output = self.handle(*args, **options) File "C:\Users\timmeh\source\Python Projects\Django Projects\env\myproject\topxgym\members\management\commands\active.py", line 20, in handle msg = WhatsApp(name, phone, date) File "C:\Users\timmeh\source\Python Projects\Django Projects\env\myproject\topxgym\members\management\commands\whatsapp.py", line 14, in __init__ self.authorization = self.config['Auth']['Authorization'] File "C:\Users\timmeh\AppData\Local\Programs\Python\Python310\lib\configparser.py", line 964, in __getitem__ raise KeyError(key) KeyError: 'Auth'
但把whatsapp.py移到独立文件夹直接运行时,程序能正常工作。
相关代码
active.py 内容
from turtle import update from django.core.management.base import BaseCommand, CommandError from members.models import ActiveMember from datetime import datetime, timedelta from .whatsapp import WhatsApp class Command(BaseCommand): help = 'Deactivate expired memberships!' def handle(self, *args, **options): ActiveMember.objects.filter(end_date__lt=datetime.now().date()).update(status='2') expired_memberships = ActiveMember.objects.filter(end_date=datetime.now().date()) for expired in expired_memberships: name = expired.member.full_name phone = expired.member.phone date = expired.end_date msg = WhatsApp(name, phone, date) msg.send_message()
whatsapp.py 内容
import requests from configparser import ConfigParser from datetime import datetime class WhatsApp(): def __init__(self, name, phone, date): self.required_len = len(name) + 2 self.config = ConfigParser() self.config.read('config.ini') self.name = name.center(self.required_len) self.phone = add_suffix(self, phone) self.date = date self.authorization = self.config['Auth']['Authorization'] self.token = self.config['Auth']['Token'] self.phone_number_id = self.config['Auth']['phone_number_id'] self.whatsapp_business_account_id = self.config['Auth']['whatsapp_business_account_id'] def send_message(self): headers = { self.authorization: self.token, } json_data = { "messaging_product": "whatsapp", "recipient_type": "individual", "to": self.phone, "type": "template", "template": { "name": "customer_expire", "language": { "code": "en-us", }, "components": [ { "type": "body", "parameters": [ { "type": "text", "text": self.name, }, { "type": "date_time", "date_time": { "fallback_value": str(self.date) } } ] } ] } } response = requests.post(f'https://graph.facebook.com/v14.0/{self.phone_number_id}/messages', headers=headers, json=json_data) print('response = ', response) print('response.status_code = ', response.status_code) print('response.text = ', response.text) def add_suffix(self, number): number = number.lstrip('0') if number[0] == '2': return '64' + number elif number[0] == '6' and number[1] == '4': return number else: return None
问题根源
核心是工作目录不一致:
- 直接运行whatsapp.py时,程序的工作目录是
commands文件夹,所以config.read('config.ini')能找到同目录下的配置文件。 - 通过Django的manage.py执行命令时,工作目录是项目根目录(
topxgym),此时config.ini不在根目录,导致配置文件没被加载,ConfigParser里没有'Auth'节,触发KeyError。
另外,add_suffix函数定义错误:它是普通函数却带了self参数,调用时会把WhatsApp实例传进去,导致参数错误。
修复方案
1. 修正配置文件读取路径
修改whatsapp.py中读取config.ini的代码,用绝对路径定位配置文件:
import os # 新增导入os模块 import requests from configparser import ConfigParser from datetime import datetime class WhatsApp(): def __init__(self, name, phone, date): self.required_len = len(name) + 2 self.config = ConfigParser() # 获取当前脚本所在目录的绝对路径 current_dir = os.path.dirname(os.path.abspath(__file__)) # 拼接config.ini的绝对路径 config_file_path = os.path.join(current_dir, 'config.ini') self.config.read(config_file_path) # 后续代码不变...
2. 修正add_suffix函数
去掉函数的self参数,调用时直接传phone:
def add_suffix(number): # 去掉self参数 number = number.lstrip('0') # 增加长度判断,避免索引越界 if len(number) > 0 and number[0] == '2': return '64' + number elif len(number) >=2 and number[0] == '6' and number[1] == '4': return number else: return None
然后在WhatsApp类的__init__方法中修改调用:
self.phone = add_suffix(phone) # 去掉self参数
验证修改
完成上述修改后,重新运行python manage.py active,程序就能正确读取config.ini中的配置,不再出现KeyError,同时也能正确处理手机号后缀。
内容的提问来源于stack exchange,提问作者wormy505
相关产品推荐
相关产品推荐

