skip to Main Content

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


  1. Chosen as BEST ANSWER

    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:

    1. The .env file was located in the same folder as manage.py. I moved it to the parent folder, in the same folder as venv.
    2. I "downgraded" the running process from launching as root to user.
    3. I ran sudo chown user:user to match the current user.
    4. I added home variable to Apache config file for the DaemonProcess as suggested by Abdul

    Now the website is fully online and the database operational.

    Thanks for everyone's help.


  2. Your AUTH_USER_MODEL setting [Django-doc] is somehow set to None, like:

    # settings.py
    
    AUTH_USER_MODEL = None

    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 returned None.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search