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

Django应用部署到Apache时出现ForeignKey(None)错误求助

问题:Django部署到Apache出现ForeignKey(None)无效的500错误

问题现象

Django Web应用在Nginx上部署测试正常,但切换到Apache后触发500服务器错误,核心报错:

TypeError: ForeignKey(None) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string 'self'

Apache错误日志回溯

[Tue Aug 06 19:48:10.945075 2024] [wsgi:error] [pid 344644] [remote 169.255.52.63:23675]   File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
[Tue Aug 06 19:48:10.945077 2024] [wsgi:error] [pid 344644] [remote 169.255.52.63:23675]   File "<frozen importlib._bootstrap_external>", line 883, in exec_module
[Tue Aug 06 19:48:10.945079 2024] [wsgi:error] [pid 344644] [remote 169.255.52.63:23675]   File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
[Tue Aug 06 19:48:10.945082 2024] [wsgi:error] [pid 344644] [remote 169.255.52.63:23675]   File "/var/www/mysite/vir/lib/python3.10/site-packages/django/contrib/admin/models.py", line 48, in <module>
[Tue Aug 06 19:48:10.945086 2024] [wsgi:error] [pid 344644] [remote 169.255.52.63:23675]     class LogEntry(models.Model):
[Tue Aug 06 19:48:10.945089 2024] [wsgi:error] [pid 344644] [remote 169.255.52.63:23675]   File "/var/www/mysite/vir/lib/python3.10/site-packages/django/contrib/admin/models.py", line 54, in LogEntry
[Tue Aug 06 19:48:10.945090 2024] [wsgi:error] [pid 344644] [remote 169.255.52.63:23675]     user = models.ForeignKey(
[Tue Aug 06 19:48:10.945092 2024] [wsgi:error] [pid 344644] [remote 169.255.52.63:23675]   File "/var/www/mysite/vir/lib/python3.10/site-packages/django/db/models/fields/related.py", line 959, in __init__
[Tue Aug 06 19:48:10.945094 2024] [wsgi:error] [pid 344644] [remote 169.255.52.63:23675]     raise TypeError(
[Tue Aug 06 19:48:10.945099 2024] [wsgi:error] [pid 344644] [remote 169.255.52.63:23675] TypeError: ForeignKey(None) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string 'self'

异常来源代码

def __init__(
        self,
        to,
        on_delete,
        related_name=None,
        related_query_name=None,
        limit_choices_to=None,
        parent_link=False,
        to_field=None,
        db_constraint=True,
        **kwargs,
    ):
        try:
            to._meta.model_name
        except AttributeError:
            if not isinstance(to, str):
                raise TypeError(
                    "%s(%r) is invalid. First parameter to ForeignKey must be "
                    "either a model, a model name, or the string %r"
                    % (
                        self.__class__.__name__,
                        to,
                        RECURSIVE_RELATIONSHIP_CONSTANT,
                    )
                )

已尝试操作

  • 修改DB_HOST为服务器地址,触发套接字错误
  • 修改PostgreSQL套接字组所属为www-data,500错误依旧
  • 本地运行./manage.py dbshell可正常连接数据库

相关配置文件

Apache虚拟主机配置

<VirtualHost *:80>
        ServerAdmin admin@adminsite.com
        DocumentRoot /var/www/mysite
        ServerName mysite.com
    Alias /static /var/www/mysite/portal/static

    <Directory /var/www/mysite/portal/static>
        Require all granted
    </Directory>
    Alias /media /home/admin/media
    <Directory /home/admin/media>
                Require all granted
        </Directory>
    <Directory /var/www/mysite/portal/portal>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>
    WSGIDaemonProcess portal python-path=/var/www/mysite/portal python-home=/var/www/mysite/vir
    WSGIProcessGroup portal
    WSGIScriptAlias / /var/www/mysite/portal/portal/wsgi.py
    ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

wsgi.py内容

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'portal.settings')

application = get_wsgi_application()

settings.py关键配置

WSGI_APPLICATION = 'portal.wsgi.application'


# Database
DATABASES = {
   'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': os.getenv('DB_NAME'),
        'USER': os.getenv('DB_USER'),
        'PASSWORD': os.getenv('DB_PASSWORD'),
        'HOST': os.getenv('DB_HOST'),
        'PORT': ''
   }
}

# User authentication
AUTH_USER_MODEL = os.getenv("AUTH_USER_MODEL")
AUTHENTICATION_BACKENDS = ['login.backends.EmailBackend',]

环境变量取值:DB_HOST=127.0.0.1,AUTH_USER_MODEL='login.CustomUser'

目录结构

.
├── portal
│   ├── login
│   ├── manage.py
│   ├── portal
│   ├── static
│   ├── templates
│   └── web
├── README.md
├── requirements.txt
└── vir
    ├── bin
    ├── include
    ├── lib
    ├── lib64 -> lib
    └── pyvenv.cfg

排查思路与解决方案

  1. 环境变量未加载导致AUTH_USER_MODEL为None

    • 验证:在wsgi.py中添加print(os.getenv('AUTH_USER_MODEL')),重启Apache后查看错误日志是否输出正确值。若输出None,说明环境变量未被WSGI进程读取。
    • 解决:
      • 直接在Apache配置的WSGIDaemonProcess行后添加环境变量:
        WSGIDaemonProcess portal python-path=/var/www/mysite/portal python-home=/var/www/mysite/vir env=AUTH_USER_MODEL='login.CustomUser' env=DB_NAME='你的数据库名' env=DB_USER='你的数据库用户' env=DB_PASSWORD='你的数据库密码' env=DB_HOST='127.0.0.1'
        
      • 或使用python-dotenv管理环境变量,确保wsgi.py中先加载.env文件:
        import os
        from dotenv import load_dotenv
        
        load_dotenv()  # 加载.env文件
        from django.core.wsgi import get_wsgi_application
        
        os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'portal.settings')
        
        application = get_wsgi_application()
        
  2. WSGI进程权限不足

    • 检查环境变量文件(如.env)的权限,确保www-data用户可读取:
      chmod 644 /var/www/mysite/.env
      chown :www-data /var/www/mysite/.env
      
  3. 自定义User模型加载顺序错误

    • 确保loginapp在INSTALLED_APPS中排在django.contrib.admin之前,让Django优先加载自定义User模型。
  4. 数据库连接验证

    • 用www-data用户测试数据库连接:
      sudo -u www-data psql -h 127.0.0.1 -U 你的数据库用户 你的数据库名
      
      输入密码后若无法连接,需调整PostgreSQL的pg_hba.conf配置,允许localhost的www-data用户访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 21:24:51