TypeError: ForeignKey(None) недопустим. Первым параметром ForeignKey должна быть либо модель, либо имя модели, либо строка 'self'.
Я не новичок в Django, но я новичок в Apache. Недавно я разработал веб-приложение и протестировал его развертывание на Nginx, и оно работало просто отлично. Однако клиент предпочитает Apache, и я создал файл конфигурации. После этого я получаю ошибку сервера 500, и появляется приведенная выше ошибка.
Ниже приведена часть трассировки в журнале ошибок 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'
Я открыл django/db/models/fields/related.py
и нашел источник исключения:
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,
)
)
Я знаю, что это определенно связано с невозможностью установить соединение с базой данных Postgres, но что именно является причиной этого?
- Я попробовал изменить хост db на хост сервера. Я получаю ошибку сокета .
- Я также изменил принадлежность группы сокетов psql на www-data, но ошибка 500 сервера сохраняется.
Запуск ./manage.py dbshell
работает просто отлично.
Вот мой файл конфигурации Apache:
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
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()
Любое понимание было бы очень признательно. Спасибо!
EDIT
Я отредактировал, чтобы добавить часть моего файла settings.py:
WSGI_APPLICATION = 'portal.wsgi.application'
# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
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
и сервер находится на 41.XX.XX.XX
, 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
Ваша AUTH_USER_MODEL
настройка [Django-doc] почему-то установлена на None
, например:
# settings.py
AUTH_USER_MODEL = None
Вероятно, не явно. Вы могли использовать, например, переменную окружения, которая не была установлена, или что-то еще.
Посмотрите, что задает параметр AUTH_USER_MODEL
, и как он возвращает None
.
Мне удалось решить эту проблему. Load_env()
действительно не отображались переменные окружения: секретный ключ, имя базы данных, хост и т. д.
Вот что я сделал:
- Файл
.env
находился в той же папке, что иmanage.py
. Я переместил его в родительскую папку, в ту же папку, что иvenv
. - Я "понизил" уровень запущенного процесса с
root
доuser
. - Я запустил
sudo chown user:user
для соответствия текущему пользователю. - Я добавил переменную
home
в файл конфигурации Apache для DaemonProcess, как предложил Абдул .
Теперь веб-сайт полностью запущен, а база данных работает.
Спасибо всем за помощь.