I recently developed a web app and tested its deployment on Nginx and it worked just fine. The client has a preference for Apache though and I created a config file. After this, I am getting a 500 server error and the error above is presenting itself.
Below is part of the traceback in the Apache error log:
[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'
I opened django/db/models/fields/related.py
and found the source of the exception:
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,
)
)
I know this definitely has to do with failure to establish a connection to the Postgres db but what is exactly causing this?
- I have tried changing the db host to that of the server. I get a socket error
- I have also changed the psql socket group ownership to www-data but the 500 server error persists.
Running ./manage.py dbshell
is working just fine.
Here is my Apache config file:
<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 [email protected]
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>
and this is the wsgi.py
file:
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'portal.settings')
application = get_wsgi_application()
Any insight would be greatly appreciated. Thanks!
EDIT
I’ve edited to add part of my settings.py file:
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',]
where DB_HOST
= 127.0.0.1
and the server is on 41.XX.XX.XX
, AUTH_USER_MODEL
= 'login.CustomUser'
and directory tree:
.
├── portal
│ ├── login
│ ├── manage.py
│ ├── portal
│ ├── static
│ ├── templates
│ └── web
├── README.md
├── requirements.txt
└── vir
├── bin
├── include
├── lib
├── lib64 -> lib
└── pyvenv.cfg
2
Answers
I managed to solve it.
Load_env()
was indeed not rendering the environment variables: secret key, database name, host etc. Here are the things I did:.env
file was located in the same folder asmanage.py
. I moved it to the parent folder, in the same folder asvenv
.root
touser
.sudo chown user:user
to match the current user.home
variable to Apache config file for the DaemonProcess as suggested by AbdulNow the website is fully online and the database operational.
Thanks for everyone's help.
Your
AUTH_USER_MODEL
setting [Django-doc] is somehow set toNone
, like:Probably not explicitly though. You might have used for example an environment variable that was not set, or something else.
Look what is setting the
AUTH_USER_MODEL
setting, and how that returnedNone
.