admin管理员组

文章数量:1384438

I am deploying my Django Rest API to a web server running on Ubuntu 24.04 LTS Linux and using the Apache web server. This web server is external; I have not set it up, and so some of the details on how it works is a blackbox to me.

I have run into a very annoying error in which I will get a 500 error saying "Server got itself in trouble" whenever I add payload to any sort of request. It doesn't matter the method: it can be a GET, POST, PUT, PATCH or DELETE and it will still run into the error...

However, when I run a request without a payload, I don't run into this error (I run into expected errors for not including expected request data instead)...

Here are some details on the server, that could give insight:

  • The app runs within a Gunicorn container
  • Client requests go to a reverse proxy and they are redirected to the app
  • The app handles incoming requests and is listening out for them

Here is also the settings.py I am using. I have DEBUG=True for now to try to get to the root of the issue...

"""
Django settings for server project.

Generated by 'django-admin startproject' using Django 5.1.4.

For more information on this file, see
.1/topics/settings/

For the full list of settings and their values, see
.1/ref/settings/
"""

from pathlib import Path
from datetime import timedelta
from cryptography.fernet import Fernet
import sys
import environ 
import os

env = environ.Env()
environ.Env.read_env()

USE_X_FORWARDED_HOST = True

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

# Quick-start development settings - unsuitable for production
# See .1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-(ltwgqma)#6=y3!dcw4b&8sog&%y@i51d1ye*(w_fk$9p0tvip'

ENCRYPTED_FIELDS_KEY = env('ENCRYPTED_FIELDS_KEY')

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*']


# Application definition

INSTALLED_APPS = [
    'daphne',
    'django_eventstream',
    
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
    'django_extensions',
    
    'django_apscheduler',
    'rest_framework',
    'rest_framework_simplejwt.token_blacklist',
    'corsheaders',
    
    'apps.api'
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middlewaremon.CommonMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middlewaremon.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'server.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

# WSGI_APPLICATION = 'server.wsgi.application'
ASGI_APPLICATION = "server.asgi.application"

# Database
# .1/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': 'server',
        'NAME': env('DB_NAME'),
        'USER': env('DB_USERNAME'),
        'PASSWORD': env('DB_PASSWORD')
    }
}

# Password validation
# .1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True

FIXTURE_DIRS = [
    'fixtures'
]

STATIC_URL = 'static/'

MEDIA_ROOT =  os.path.join(os.path.dirname(BASE_DIR), "server/media")

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

CORS_ALLOW_ALL_ORIGINS = True

AUTH_USER_MODEL = "users.User"

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ],
     'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
    ],
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
    ]
}
SIMPLE_JWT = {
     'ACCESS_TOKEN_LIFETIME': timedelta(minutes=10),
     'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
     'ROTATE_REFRESH_TOKENS': True,
     'BLACKLIST_AFTER_ROTATION': False,
     
     'USER_ID_FIELD': 'user_id'
}

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
        },
    },
    "root": {
        "handlers": ["console"],
        "level": "WARNING",
    },
}

if 'test' in sys.argv:
    DATABASES['default'] = {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'test'
    }

There are logs I can access, but there is nothing there other than api/users 404: Bad request that indicate the error.

Thank you to anyone who can help me get to the bottom on this!

EDIT: I solved the issue with the people behind this web server. Their documentation said that using "a2wsgi" would provide a compatibility layer, and I thought I could use that. However, it didn't work happily with django_eventstream, hence there were async failures. Changing to the expected WSGI and using an alternative to django_eventstream solved the issue

I am deploying my Django Rest API to a web server running on Ubuntu 24.04 LTS Linux and using the Apache web server. This web server is external; I have not set it up, and so some of the details on how it works is a blackbox to me.

I have run into a very annoying error in which I will get a 500 error saying "Server got itself in trouble" whenever I add payload to any sort of request. It doesn't matter the method: it can be a GET, POST, PUT, PATCH or DELETE and it will still run into the error...

However, when I run a request without a payload, I don't run into this error (I run into expected errors for not including expected request data instead)...

Here are some details on the server, that could give insight:

  • The app runs within a Gunicorn container
  • Client requests go to a reverse proxy and they are redirected to the app
  • The app handles incoming requests and is listening out for them

Here is also the settings.py I am using. I have DEBUG=True for now to try to get to the root of the issue...

"""
Django settings for server project.

Generated by 'django-admin startproject' using Django 5.1.4.

For more information on this file, see
https://docs.djangoproject/en/5.1/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject/en/5.1/ref/settings/
"""

from pathlib import Path
from datetime import timedelta
from cryptography.fernet import Fernet
import sys
import environ 
import os

env = environ.Env()
environ.Env.read_env()

USE_X_FORWARDED_HOST = True

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject/en/5.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-(ltwgqma)#6=y3!dcw4b&8sog&%y@i51d1ye*(w_fk$9p0tvip'

ENCRYPTED_FIELDS_KEY = env('ENCRYPTED_FIELDS_KEY')

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*']


# Application definition

INSTALLED_APPS = [
    'daphne',
    'django_eventstream',
    
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
    'django_extensions',
    
    'django_apscheduler',
    'rest_framework',
    'rest_framework_simplejwt.token_blacklist',
    'corsheaders',
    
    'apps.api'
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middlewaremon.CommonMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middlewaremon.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'server.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

# WSGI_APPLICATION = 'server.wsgi.application'
ASGI_APPLICATION = "server.asgi.application"

# Database
# https://docs.djangoproject/en/5.1/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': 'server',
        'NAME': env('DB_NAME'),
        'USER': env('DB_USERNAME'),
        'PASSWORD': env('DB_PASSWORD')
    }
}

# Password validation
# https://docs.djangoproject/en/5.1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True

FIXTURE_DIRS = [
    'fixtures'
]

STATIC_URL = 'static/'

MEDIA_ROOT =  os.path.join(os.path.dirname(BASE_DIR), "server/media")

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

CORS_ALLOW_ALL_ORIGINS = True

AUTH_USER_MODEL = "users.User"

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ],
     'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
    ],
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
    ]
}
SIMPLE_JWT = {
     'ACCESS_TOKEN_LIFETIME': timedelta(minutes=10),
     'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
     'ROTATE_REFRESH_TOKENS': True,
     'BLACKLIST_AFTER_ROTATION': False,
     
     'USER_ID_FIELD': 'user_id'
}

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
        },
    },
    "root": {
        "handlers": ["console"],
        "level": "WARNING",
    },
}

if 'test' in sys.argv:
    DATABASES['default'] = {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'test'
    }

There are logs I can access, but there is nothing there other than api/users 404: Bad request that indicate the error.

Thank you to anyone who can help me get to the bottom on this!

EDIT: I solved the issue with the people behind this web server. Their documentation said that using "a2wsgi" would provide a compatibility layer, and I thought I could use that. However, it didn't work happily with django_eventstream, hence there were async failures. Changing to the expected WSGI and using an alternative to django_eventstream solved the issue

Share Improve this question edited Mar 20 at 15:17 fiocotti asked Mar 17 at 20:22 fiocottifiocotti 752 silver badges7 bronze badges 1
  • When you say payload, what exactly do you mean? In the screenshots, at least two separate variables are changing between the "success" and error scenarios - headers and body. What happens if you include auth headers but no payload, and you query a GET endpoint? Also, check daphne logs, that's where the exception is raised. – Vegard Commented Mar 18 at 21:56
Add a comment  | 

2 Answers 2

Reset to default 0

The error appears to be occurring because the view isn't checking if the user is authenticated before accessing its attributes. Django uses AnonymousUser to handle unauthenticated user sessions, and this model doesn't have a user_id field, which is causing the 500 error.

Check your view to see if you're ensuring the user is authenticated before attempting to access the user_id. Something like this might help:

if not request.user.is_authenticated:
    return JsonResponse({"error": "User not authenticated"}, status=401)

However, to help you better, could you share the code for your full view? Specifically, how you're getting the user and accessing their attributes.

Please login first then then run the api , if you don't have any login page you can trying login from you django admin login page and try hiting the API.

本文标签: