I created a django project tha uses a customUser for authentication, following this blog post.
I now would like to attach another app to the project that is a REST API that leverages that authentication.
In this new app I create a model for the data that the uses will consume and I add as foreign key in the model the custom user model previously created.
#project/api/models.py
from django.contrib.postgres.fields import ArrayField
from django.db import models
from accounts.models import CustomUser
class Signal(models.Model):
name = models.CharField(max_length=30, blank=True, null=True)
data = ArrayField(models.FloatField(), unique=True)
threshold = models.FloatField(blank=True, null=True)
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
def __str__(self) -> str:
return f"{self.name}"
while the project/api/views.py file is
from django.template.defaultfilters import pluralize
from rest_framework.decorators import api_view
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.request import Request
from rest_framework.response import Response
from . import serializers
from .algorithm.compute_crossing import count_crossing_pos as count_cross
from .models import Signal
class SignalViewset(ListCreateAPIView):
permission_classes = [IsAuthenticated]
queryset = Signal.objects.all()
serializer_class = serializers.SignalSerializer
def get_queryset(self):
return super().get_queryset().filter(user=self.request.user)
class SignalDetail(RetrieveUpdateDestroyAPIView):
permission_classes = [IsAuthenticated]
queryset = Signal.objects.all()
serializer_class = serializers.SignalSerializer
def get_queryset(self):
return super().get_queryset().filter(user=self.request.user)
#api_view(http_method_names=["POST"])
def send_data(request: Request) -> Response():
"""send signal data with threshold in request payload
and compute crossing times around given threshold
:param request: [request payload]
:type request: [type]
"""
if request.user.is_authenticated:
count = count_cross(request.data.get("data"), request.data.get("threshold"))
return Response(
{
"status": "success",
"info": "signal crosses the given threshold {} tim{}".format(
count, pluralize(count, "e,es")
),
"count": str(count),
},
status=200,
)
else:
count = count_cross(request.data.get("data"), request.data.get("threshold"))
return Response(
{
"status": "success",
"info": "you are an AnonymousUser but I will give you an answer nonetheless \n \n signal crosses the given threshold {} tim{}".format(
count, pluralize(count, "e,es")
),
"count": str(count),
},
status=200,
)
Everytime I access the send_data endpoint I go into the else statement as request.user.is_authenticated is False.
how do I connect the rest api with the authentication (accounts) app?
my settings.py file is:
from pathlib import Path
from decouple import config
# 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.com/en/3.2/howto/deployment/checklist/
SYSTEM_ENV = config("SYSTEM_ENV")
ALLOWED_HOSTS = [
"*",
]
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"api",
"rest_framework",
"rest_framework.authtoken",
"dj_rest_auth",
"django.contrib.sites",
"allauth",
"allauth.account",
"dj_rest_auth.registration",
"accounts",
]
AUTH_USER_MODEL = "accounts.CustomUser" # new
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "signal_crossing.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [str(BASE_DIR.joinpath("templates"))],
"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 = "signal_crossing.wsgi.application"
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
if SYSTEM_ENV == "PRODUCTION" or SYSTEM_ENV == "STAGING":
print("docker")
DEBUG = False
SECRET_KEY = config("SECRET_KEY")
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"NAME": "postgres",
"USER": "postgres",
"PASSWORD": "postgres",
"HOST": "db",
"PORT": 5432,
}
}
elif SYSTEM_ENV == "GITHUB_WORKFLOW":
DEBUG = True
SECRET_KEY = "TESTING_KEY"
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"NAME": "github_actions",
"USER": "postgres",
"PASSWORD": "postgres",
"HOST": "127.0.0.1",
"PORT": "5432",
}
}
elif SYSTEM_ENV == "DEVELOPMENT":
DEBUG = True
SECRET_KEY = "DEVELOP_KEY"
# DATABASES = {
# "default": {
# "ENGINE": "django.db.backends.postgresql_psycopg2",
# "NAME": config("DB_NAME"),
# "USER": config("POSTGRES_LOCAL_USER"),
# "PASSWORD": config("POSTGRES_LOCAL_PASSWORD"),
# "HOST": "localhost",
# "PORT": "5432",
# }
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
# Password validation
# https://docs.djangoproject.com/en/3.2/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",
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = "/static/"
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
SITE_ID = 1
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
# 'rest_framework.authentication.TokenAuthentication',
"dj_rest_auth.jwt_auth.JWTCookieAuthentication",
],
}
REST_USE_JWT = True
JWT_AUTH_COOKIE = "my-app-auth"
AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.ModelBackend",
# allauth specific authentication methods, such as login by e-mail
"allauth.account.auth_backends.AuthenticationBackend",
# Needed to login by username in Django admin, regardless of allauth
"django.contrib.auth.backends.ModelBackend",
]
# ACCOUNT_AUTHENTICATION_METHOD = "username"
# LOGIN_URL = "/login/"
# LOGIN_REDIRECT_URL = "/"
# LOGOUT_REDIRECT_URL = "/"
DJANGO_SETTINGS_MODULE = "signal_crossing.settings"
LOGIN_REDIRECT_URL = "home"
LOGOUT_REDIRECT_URL = "home"
Related
I have built a server with Django and I am receiving a 400 Bad Request within Postman when I check the POST method. However, it is displaying the JSON data within the Postman as well.
Originally, I thought it was a frontend issue, because my console log was stating
AxiosError {message: 'Request failed with status code 400', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}
As I stated before, the error is showing in Postman so I'm assuming it's actually a server issue.
Im real "finicky" when it comes to file colors, and if it is any color than the default color, I feel like there is errors within the file. Could these orange/beige files contain the problem? If I click on one of those files Im met with:
The file is not displayed in the editor because it is either binary or uses an unsupported text encoding.
Because I am new to django, I don't want to do something that's going to create an even bigger problem than what I already have.
Below will be my settings.py
"""
Django settings for django_rest_api project.
Generated by 'django-admin startproject' using Django 4.1.4.
For more information on this file, see
https://docs.djangoproject.com/en/4.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.1/ref/settings/
"""
from pathlib import Path
# 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.com/en/4.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "django-insecure-2r=5^!2(nj*^*m*sa_39h(xldjpau&$wmn&pc5=^frws#w&25="
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
"corsheaders",
"rest_framework",
"todo_api",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
CORS_ALLOW_ALL_ORIGINS = True
ROOT_URLCONF = "django_rest_api.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 = "django_rest_api.wsgi.application"
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "todo_api",
"USER": "",
"PASSWORD" : '',
"HOST": "localhost"
}
}
# Password validation
# https://docs.djangoproject.com/en/4.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",
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.1/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.1/howto/static-files/
STATIC_URL = "static/"
# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
Below is my views.py
from django.shortcuts import render
from rest_framework import generics
from .serializer import TodoSerializer
from .models import Todo
# Create your views here.
class TodoList(generics.ListCreateAPIView):
queryset = Todo.objects.all().order_by('id')
serializer_class = TodoSerializer
class TodoDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Todo.objects.all().order_by('id')
serializer_class = TodoSerializer
Im not exactly sure what information everyone needs to provide a proper solution for this, but hopefully I have provided more than enough.
I think it is worth noting that I am using postgreql and my database is working properly, and I can access Django admin and manually enter data from there as well.
I have created a vue and DRF application, which is working fine locally, it sets access, refresh and csrf token in cookies on login and so all of the isAuthenticated routes work fine.
But i handed it over to the person who's meant to deploy this on vps and now it doesn't set cookie on login. I'm able to login, but since no cookie is set, refreshing it logs me out and all routes give 401 error.
These are my django settings, removing secret_key here:
import os
from pathlib import Path
from datetime import timedelta
# 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.com/en/3.2/howto/deployment/checklist/
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework_api_key',
'rest_framework_simplejwt.token_blacklist',
'corsheaders',
'django_filters',
'api'
]
AUTH_USER_MODEL = 'api.User'
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.AllowAllUsersModelBackend',
)
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOW_HEADERS = [
"accept",
"accept-encoding",
"authorization",
"content-type",
"dnt",
"origin",
"user-agent",
"x-csrftoken",
"x-requested-with",
"fxbNh4",
]
# CORS_ALLOWED_ORIGINS = [
# "http://localhost:8080"
# ]
# CORS_ALLOWED_ORIGINS = [
# 'http://34.67.29.99',
# ]
CORS_ALLOW_CREDENTIALS = True
ROOT_URLCONF = 'InstaBackend.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR)],
'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 = 'InstaBackend.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.2/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',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Asia/Karachi'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',
),
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 12,
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated'
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'api.authenticate.CustomAuthentication',
),
'DATETIME_FORMAT': "%Y-%m-%d %H:%M:%S",
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(days=1),
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': True,
'UPDATE_LAST_LOGIN': False,
'ALGORITHM': 'HS256',
'SIGNING_KEY': SECRET_KEY,
'VERIFYING_KEY': None,
'AUDIENCE': None,
'ISSUER': None,
'AUTH_HEADER_TYPES': ('Bearer',),
'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'JTI_CLAIM': 'jti',
'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
'AUTH_ACCESS_COOKIE': 'access_token', # Cookie name. Enables cookies if value is set.
'AUTH_REFRESH_COOKIE': 'refresh_token', # Cookie name. Enables cookies if value is set.
'AUTH_CSRF_ACCESS_COOKIE': 'csrf_access_token', # Cookie name. Enables cookies if value is set.
'AUTH_CSRF_REFRESH_COOKIE': 'csrf_refresh_token', # Cookie name. Enables cookies if value is set.
'AUTH_COOKIE_DOMAIN': None, # A string like "example.com", or None for standard domain cookie.
'AUTH_COOKIE_SECURE': False, # Whether the auth cookies should be secure (https:// only).
'AUTH_COOKIE_HTTP_ONLY': False, # Http only cookie flag.It's not fetch by javascript.
'AUTH_COOKIE_PATH': '/', # The path of the auth cookie.
'AUTH_COOKIE_SAMESITE': None, # Whether to set the flag restricting cookie leaks on cross-site requests.
# This can be 'Lax', 'Strict', or None to disable the flag.
}
# CSRF_COOKIE_DOMAIN = '34.67.29.99'
# # CSRF_COOKIE_SECURE = True
# # USE_X_FORWARDED_HOST = True
# # SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
# CSRF_TRUSTED_ORIGINS = ['http://34.67.29.99/','http://34.67.29.99',]
# CSRF_COOKIE_SAMESITE = 'Lax'
# CSRF_COOKIE_HTTPONLY = False
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
This is how I set cookies :
def set_access_cookies(response, access_token):
response.set_cookie(
key=settings.SIMPLE_JWT['AUTH_ACCESS_COOKIE'],
value=access_token,
expires=settings.SIMPLE_JWT['ACCESS_TOKEN_LIFETIME'],
secure=settings.SIMPLE_JWT['AUTH_COOKIE_SECURE'],
httponly=settings.SIMPLE_JWT['AUTH_COOKIE_HTTP_ONLY'],
samesite=settings.SIMPLE_JWT['AUTH_COOKIE_SAMESITE']
)
def set_refresh_cookies(response, refresh_token):
response.set_cookie(
key=settings.SIMPLE_JWT['AUTH_REFRESH_COOKIE'],
value=refresh_token,
expires=settings.SIMPLE_JWT['REFRESH_TOKEN_LIFETIME'],
secure=settings.SIMPLE_JWT['AUTH_COOKIE_SECURE'],
httponly=settings.SIMPLE_JWT['AUTH_COOKIE_HTTP_ONLY'],
samesite=settings.SIMPLE_JWT['AUTH_COOKIE_SAMESITE']
)
This is my login_view:
from django.middleware import csrf
from rest_framework.views import APIView
from rest_framework.response import Response
from django.contrib.auth import authenticate
from rest_framework import status
from api.util import (set_access_cookies, set_refresh_cookies, get_tokens_for_user, combine_role_permissions,
extract_patient_role)
from api.serializers import UserSerializer, RoleSerializer
from django.utils import timezone
from api.models import User
from rest_framework_api_key.permissions import HasAPIKey
from rest_framework.permissions import AllowAny
class LoginView(APIView):
authentication_classes = ()
permission_classes = (HasAPIKey,)
# permission_classes = (AllowAny,)
def post(self, request):
try:
data = request.data
response = Response()
username = data.get('username', None)
password = data.get('password', None)
try:
User.objects.get(email = username)
except User.DoesNotExist:
return Response({"msg": "User Credentails don't exist ! "}, status=status.HTTP_400_BAD_REQUEST)
user = authenticate(username=username, password=password)
if user.is_approved:
if user is not None:
role, roles = extract_patient_role(user.roles.all())
permissions = combine_role_permissions(roles)
data = get_tokens_for_user(user, is_patient=False)
set_access_cookies(response, data['access'])
set_refresh_cookies(response, data['refresh'])
csrf.get_token(request)
data = UserSerializer(user, context={'request': request}).data
data['roles'] = RoleSerializer(roles, many=True).data
data['permissions'] = permissions
response.status_code = status.HTTP_200_OK
response.data = {"msg": "Login successfully", "user": data}
user.last_login = timezone.now()
user.save()
return response
else:
return Response({"msg": "Invalid credentials"}, status=status.HTTP_404_NOT_FOUND)
else:
return Response({"msg": "Please verify account to log in"}, status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
print(e)
return Response({"msg": "Unable to Login"}, status=status.HTTP_400_BAD_REQUEST)
This is the axios instance for logging in:
import Vue from "vue";
import axios from "axios";
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== "") {
var cookies = document.cookie.split(";");
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === name + "=") {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const axiosIns2 = axios.create({
baseURL: process.env.VUE_APP_API,
withCredentials: true,
xsrfCookieName: "csrftoken",
xsrfHeaderName: "X-CSRFTOKEN",
headers: {
"X-CSRFTOKEN": getCookie("csrftoken"),
Authorization: "Api-Key " + process.env.VUE_APP_KEY,
},
});
Vue.prototype.$http = axiosIns2;
export default axiosIns2;
And this is the axios instance for other authenticated requests:
import Vue from "vue";
import axios from "axios";
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== "") {
var cookies = document.cookie.split(";");
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === name + "=") {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const axiosIns = axios.create({
baseURL: process.env.VUE_APP_API,
withCredentials: true,
xsrfCookieName: "csrftoken",
xsrfHeaderName: "X-CSRFTOKEN",
headers: {
"X-CSRFTOKEN": getCookie("csrftoken"),
},
});
const COOKIE_EXPIRED_MSG = "Token is invalid or expired";
axiosIns.interceptors.response.use(
(response) => {
return response;
},
async (error) => {
let error_message = null;
if (error.response.data.messages) {
error_message = error.response.data.messages[0].message;
}
switch (error.response.status) {
case 401:
if (!error.config.retry && error_message === COOKIE_EXPIRED_MSG) {
error.config.retry = true;
// axiosIns.defaults.xsrfCookieName = "csrf_refresh_token";
await axiosIns.post("/refresh");
// axiosIns.defaults.xsrfCookieName = "csrf_access_token";
return axiosIns(error.config);
} else {
throw new Error("Error");
}
break;
default:
break;
}
return Promise.reject(error);
}
);
Vue.prototype.$http = axiosIns;
export default axiosIns;
VPS OS Details:
Ubuntu 18.04.6
I currently don't have access to VPS, i believe this issue is due to SIMPLE_JWT settings in settings.py.
The project runs perfectly fine with these settings locally, but it doesn't send cookies on login when hosted. It does give 200 on login though.
Hosted Via:
Nginx , Gunicorn
The backend and frontend are hosted on 2 different hosts,
backend at : http://34.67.29.99:8080/
Frontend at : http://instasearch.convpho.com/login
I am using Django Rest Framework and OpenStack (DevStack deployed on a Virtual Machine on my local PC) to create APIs which will run methods provided by OpenStack SDK and return the response in JSON format.
However, while fetching(GET Request) a list of Servers created on OpenStack Cloud Platform, the Response for the first time after starting the Django Server is proper and desired, but after first GET Request, all GET requests sent are returning an empty List as the Response.
It must be noted that I have not changed anything in the code or in the Endpoint(URL), the same scenario keeps on repeating when I restart the Django Server, desired GET Response on first Request and Empty List for all the GET Requests onward.
I do not have any models of my own in models.py.
First GET Request Response:-
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"name": "test_shell",
"image": "openstack.image.v2.image.Image(id=b6019f25-6f6d-4fd2-9fb8-14d50a07d2c0, properties={'links': [{'rel': 'bookmark', 'href': 'http://192.168.56.101/compute/images/b6019f25-6f6d-4fd2-9fb8-14d50a07d2c0'}]})",
"flavor": "openstack.compute.v2.flavor.Flavor(vcpus=1, ram=128, disk=1, OS-FLV-EXT-DATA:ephemeral=0, swap=0, original_name=m1.nano, extra_specs={'hw_rng:allowed': 'True'})",
"networks": null,
"status": "ACTIVE",
"power_state": "1"
},
{
"name": "ins_code_4",
"image": "openstack.image.v2.image.Image(id=b6019f25-6f6d-4fd2-9fb8-14d50a07d2c0, properties={'links': [{'rel': 'bookmark', 'href': 'http://192.168.56.101/compute/images/b6019f25-6f6d-4fd2-9fb8-14d50a07d2c0'}]})",
"flavor": "openstack.compute.v2.flavor.Flavor(vcpus=1, ram=128, disk=1, OS-FLV-EXT-DATA:ephemeral=0, swap=0, original_name=m1.nano, extra_specs={'hw_rng:allowed': 'True'})",
"networks": null,
"status": "SHUTOFF",
"power_state": "4"
},
{
"name": "ins_code_3",
"image": "openstack.image.v2.image.Image(id=b6019f25-6f6d-4fd2-9fb8-14d50a07d2c0, properties={'links': [{'rel': 'bookmark', 'href': 'http://192.168.56.101/compute/images/b6019f25-6f6d-4fd2-9fb8-14d50a07d2c0'}]})",
"flavor": "openstack.compute.v2.flavor.Flavor(vcpus=1, ram=128, disk=1, OS-FLV-EXT-DATA:ephemeral=0, swap=0, original_name=m1.nano, extra_specs={'hw_rng:allowed': 'True'})",
"networks": null,
"status": "SHUTOFF",
"power_state": "4"
}
]
GET Response after first Request:-
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[]
Django Code:-
Root settings.py
from pathlib import Path
# 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.com/en/4.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-#gd5-6=)lwq4&bo(gywzy7ftic+5r!hgs$(%1gyqbt=pbwk=*a'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'api',
]
# Custom by me
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'cloudhome.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [ BASE_DIR / "templates" ],
'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 = 'cloudhome.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/4.0/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',
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = 'static/'
STATICFILES_DIRS = [
BASE_DIR / "static"
]
STATIC_ROOT = "static_root"
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
Root urls.py:-
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
path('api/', include('api.urls', namespace="api")),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
App "api" urls.py:-
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from api import views
app_name = "api"
urlpatterns = [
path('servers/', views.ServerList.as_view()),
path('servers/<slug:pk>/', views.ServerDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)
App "api" views.py:-
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from requests import request
from rest_framework.parsers import JSONParser
from api.serializers import ServerSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import generics
import openstack
from openstack import connection
from rest_framework import authentication, permissions
from rest_framework.permissions import IsAuthenticated
openstack.enable_logging(debug=True)
conn=connection.Connection(auth_url='http://192.168.56.101/identity/v3',
project_name='admin',username='admin',
password='nomoresecret',
user_domain_id='default',
project_domain_id='default', verify=False)
class ServerList(generics.ListAPIView):
queryset = conn.compute.servers()
serializer_class = ServerSerializer
permission_classes = [permissions.IsAuthenticated]
class ServerDetail(generics.RetrieveAPIView):
queryset = conn.compute.servers()
serializer_class = ServerSerializer
permission_classes = [permissions.IsAuthenticated]
App "api" serializers.py:-
import openstack
from openstack import connection
from requests import Response
from rest_framework import serializers
from rest_framework import status
openstack.enable_logging(debug=True)
conn=connection.Connection(auth_url='http://192.168.56.101/identity/v3',
project_name='admin',username='admin',
password='nomoresecret',
user_domain_id='default',
project_domain_id='default', verify=False)
class ServerSerializer(serializers.Serializer):
instance_id = serializers.CharField(read_only=True)
name = serializers.CharField(max_length=100)
image = serializers.CharField(max_length=500)
fixed_ip = serializers.IPAddressField(read_only=True)
floating_ip = serializers.IPAddressField(required=False, allow_blank=True)
flavor = serializers.CharField(max_length=500)
networks = serializers.CharField(max_length=500)
key_pair = serializers.CharField(max_length=100, required=False, allow_blank=True)
status = serializers.CharField(max_length=20, read_only=True)
power_state = serializers.CharField(max_length=20, read_only=True)
console_url = serializers.URLField(max_length=100, read_only=True)
def create(self, validated_data):
serverCreated = conn.compute.create_server(name=validated_data["instance_name"], image_id=validated_data["image_id"],
flavor_id=validated_data["flavor_id"], networks=[{"uuid": validated_data["network_id"]}])
serverWait = conn.compute.wait_for_server(serverCreated)
print(serverWait.access_ipv4)
return serverWait
Kindly help me to resolve this issue and feel free to suggest changes to make this code more efficient. Thanks in advance.
I am newbie to django and was using SQLite during development, when i moved to postgres when trying to deploy to production i get the below error
Cannot cast type time without time zone to timestamp with time zone
settings.py
Django settings for todoBackend project.
Generated by 'django-admin startproject' using Django 3.2.5.
For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
from pathlib import Path
from django.core.management.utils import get_random_secret_key
import os
import sys
import dj_database_url
# 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.com/en/3.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.getenv("DJANGO_SECRET_KEY", get_random_secret_key())
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.getenv("DEBUG", "False") == "True"
ALLOWED_HOSTS = os.getenv("DJANGO_ALLOWED_HOSTS", "127.0.0.1,localhost").split(",")
# Application definition
INSTALLED_APPS = [
"rest_framework",
"corsheaders",
"api.apps.ApiConfig",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
CORS_ALLOW_ALL_ORIGINS = True
ROOT_URLCONF = "todoBackend.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 = "todoBackend.wsgi.application"
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DEVELOPMENT_MODE = os.getenv("DEVELOPMENT_MODE", "False") == "True"
# DEVELOPMENT_MODE = True
if DEVELOPMENT_MODE is True:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
}
}
elif len(sys.argv) > 0 and sys.argv[1] != "collectstatic":
if os.getenv("DATABASE_URL", None) is None:
raise Exception("DATABASE_URL environment variable not defined")
DATABASES = {
"default": dj_database_url.parse(os.environ.get("DATABASE_URL")),
}
# Password validation
# https://docs.djangoproject.com/en/3.2/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",
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "Asia/Kolkata"
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
models.py
from django.db import models
# Create your models here.
class Tasks(models.Model):
title = models.CharField(max_length=200, blank=False, null=False)
description = models.CharField(max_length=1000, blank=True)
start_time = models.DateTimeField(blank=True, null=True)
end_time = models.DateTimeField(blank=True, null=True)
duration = models.CharField(max_length=25, blank=True)
completed = models.BooleanField(default=False)
last_modified = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
I am not sure why i am getting the error, i did setup the timezone in settings.py
The above code was working perfectly with SQLite , It only throws the error in Postgres
As #Iain shelvington in the comments pointed out , I had a migration that converted the end_time field from Character field to Time Field, Hence i was getting this error
I reset all my migrations and created a single migration which resolved the issue
I am contributing to an open-source org where they are using django-rest-auth for authentication purposes. I have to simply override the email template for a password reset. So I used imported PasswordResetSerializer and then customized it. It worked in the first place but when I restarted the whole environment it stopped working and just showed this in terminal
django_1 | [pid: 65|app: 0|req: 1/1] 172.19.0.1 () {42 vars in 696 bytes} [Thu Jan 7 22:06:59 2021] OPTIONS /api/auth/password/reset/ => generated 0 bytes in 4 msecs (HTTP/1.1 200) 7 headers in 365 bytes (1 switches on core 0)
django_1 | [pid: 67|app: 0|req: 1/2] 172.19.0.1 () {42 vars in 696 bytes} [Thu Jan 7 22:06:59 2021] POST /api/auth/password/reset/ => generated 22264 bytes in 796 msecs (HTTP/1.1 500) 5 headers in 177 bytes (1 switches on core 0)
It's showing me error 500.
I tried to use debugger but here the all environment is setup using docker and I couldn't figure out what's going wrong.
Here are the files
settings.py
"""
Django settings for evalai project.
Generated by 'django-admin startproject' using Django 1.10.2.
For more information on this file, see
https://docs.djangoproject.com/en/1.10/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.10/ref/settings/
"""
import datetime
import os
import sys
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
APPS_DIR = os.path.join(BASE_DIR, "apps")
sys.path.append(APPS_DIR)
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get("SECRET_KEY", "random_secret_key")
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEST = False
ALLOWED_HOSTS = []
EVALAI_API_SERVER = os.environ.get("EVALAI_API_SERVER", "http://localhost:8000")
# Application definition
DEFAULT_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"django.contrib.sites",
]
OUR_APPS = [
"accounts",
"analytics",
"base",
"challenges",
"hosts",
"jobs",
"participants",
"web",
]
THIRD_PARTY_APPS = [
"allauth",
"allauth.account",
'allauth.socialaccount',
"corsheaders",
"django_ses",
"import_export",
"rest_auth",
"rest_auth.registration",
"rest_framework.authtoken",
"rest_framework",
"rest_framework_expiring_authtoken",
"drf_yasg",
"django_filters",
]
INSTALLED_APPS = DEFAULT_APPS + OUR_APPS + THIRD_PARTY_APPS
MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware",
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "evalai.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 = "evalai.wsgi.application"
# Password validation
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" # noqa
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator" # noqa
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator" # noqa
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator" # noqa
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/
STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(BASE_DIR, "static")
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"
SITE_ID = 1
REST_FRAMEWORK = {
"DEFAULT_PAGINATION_CLASS": (
"rest_framework.pagination.LimitOffsetPagination"
),
"PAGE_SIZE": 100,
"TEAM_PAGE_SIZE": 10,
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticatedOrReadOnly"
],
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework_expiring_authtoken.authentication.ExpiringTokenAuthentication"
],
"TEST_REQUEST_DEFAULT_FORMAT": "json",
"DEFAULT_THROTTLE_CLASSES": (
"rest_framework.throttling.AnonRateThrottle",
"rest_framework.throttling.UserRateThrottle",
),
"DEFAULT_THROTTLE_RATES": {
"anon": "100/minute",
"user": "100/minute",
"resend_email": "3/hour",
},
"DEFAULT_RENDERER_CLASSES": ("rest_framework.renderers.JSONRenderer",),
}
# ALLAUTH SETTINGS
ACCOUNT_EMAIL_REQUIRED = True
OLD_PASSWORD_FIELD_ENABLED = True
ACCOUNT_CONFIRM_EMAIL_ON_GET = True
ACCOUNT_EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL = (
"/api/auth/email-confirmed/"
)
ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL = (
"/api/auth/email-confirmed/"
)
AUTHENTICATION_BACKENDS = (
# Needed to login by username in Django admin, regardless of `allauth`
"django.contrib.auth.backends.ModelBackend",
# `allauth` specific authentication methods, such as login by e-mail
"allauth.account.auth_backends.AuthenticationBackend",
)
AWS_STORAGE_BUCKET_NAME = os.environ.get("AWS_STORAGE_BUCKET_NAME")
AWS_ACCOUNT_ID = os.environ.get("AWS_ACCOUNT_ID", "aws_account_id")
AWS_ACCESS_KEY_ID = os.environ.get("AWS_ACCESS_KEY_ID", "aws_access_key_id")
AWS_SECRET_ACCESS_KEY = os.environ.get(
"AWS_SECRET_ACCESS_KEY", "aws_secret_access_key"
)
AWS_REGION = os.environ.get("AWS_DEFAULT_REGION", "us-east-1")
# Broker url for celery
CELERY_BROKER_URL = "sqs://%s:%s#" % (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
# CORS Settings
CORS_ORIGIN_ALLOW_ALL = True
# REST Framework Expiring Tokens Configuration
EXPIRING_TOKEN_LIFESPAN = datetime.timedelta(days=365)
# Logging
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"root": {"level": "INFO", "handlers": ["console"]},
"filters": {
"require_debug_false": {"()": "django.utils.log.RequireDebugFalse"},
"require_debug_true": {"()": "django.utils.log.RequireDebugTrue"},
},
"formatters": {
"simple": {
"format": "[%(asctime)s] %(levelname)s %(message)s",
"datefmt": "%Y-%m-%d %H:%M:%S",
},
"verbose": {
"format": "[%(asctime)s] %(levelname)s %(module)s %(message)s",
"datefmt": "%Y-%m-%d %H:%M:%S",
},
},
"handlers": {
"console": {
"level": "INFO",
"filters": ["require_debug_true"],
"class": "logging.StreamHandler",
"formatter": "simple",
},
"logfile": {
"level": "DEBUG",
"class": "logging.handlers.RotatingFileHandler",
"filename": os.path.join(BASE_DIR, "django.log"),
"maxBytes": 50000,
"backupCount": 10,
"formatter": "verbose",
},
"mail_admins": {
"level": "ERROR",
"class": "django.utils.log.AdminEmailHandler",
"filters": ["require_debug_false"],
},
},
"loggers": {
"django": {"handlers": ["console"], "propagate": False},
"django.request": {
"handlers": ["mail_admins"],
"level": "ERROR",
"propagate": False,
},
"django.security": {
"handlers": ["mail_admins"],
"level": "ERROR",
"propagate": False,
},
"django.db.backends": {
"handlers": ["mail_admins"],
"level": "ERROR",
"propagate": False,
},
},
}
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.memcached.MemcachedCache"
}
}
# The maximum size in bytes for request body
# https://docs.djangoproject.com/en/1.10/ref/settings/#data-upload-max-memory-size
FILE_UPLOAD_MAX_MEMORY_SIZE = 4294967296 # 4 GB
DATA_UPLOAD_MAX_MEMORY_SIZE = 4294967296 # 4 GB
# To make usermame field read-only, customized serializer is defined.
REST_AUTH_SERIALIZERS = {
"USER_DETAILS_SERIALIZER": "accounts.serializers.ProfileSerializer",
"PASSWORD_RESET_SERIALIZER": "accounts.serializers.CustomPasswordResetSerializer"
}
# For inviting users to participant and host teams.
ADMIN_EMAIL = "admin#cloudcv.org"
CLOUDCV_TEAM_EMAIL = "EvalAI Team <team#cloudcv.org>"
# Expiry time of a presigned url for uploading files to AWS, in seconds.
PRESIGNED_URL_EXPIRY_TIME = 3600
# Slack web hook url
SLACK_WEB_HOOK_URL = os.environ.get(
"SLACK_WEB_HOOK_URL", "http://testslackwebhook.com/webhook"
)
SWAGGER_SETTINGS = {
"DEFAULT_INFO": "evalai.urls.swagger_api_info",
"SECURITY_DEFINITIONS": {
"Token Authentication": {
"type": "apiKey",
"name": "Authorization",
"in": "header",
}
},
}
REDOC_SETTINGS = {"SPEC_URL": ("docs.yaml", {"format": ".yaml"})}
DJANGO_SERVER = os.environ.get("DJANGO_SERVER")
DJANGO_SERVER_PORT = os.environ.get("DJANGO_SERVER_PORT")
HOSTNAME = os.environ.get("HOSTNAME")
SENDGRID_SETTINGS = {
"TEMPLATES": {
"CHALLENGE_INVITATION": "d-60825bcf014f4958bdb1b9173471d420",
"CHALLENGE_APPROVAL_EMAIL": "d-45e0adc0597b4b60bd7c384aa903c488",
"WORKER_RESTART_EMAIL": "d-3d9a474a5e2b4ac4ad5a45ba9c0b84bd",
"CLUSTER_CREATION_TEMPLATE": "d-6de90fd760df4a41bb9bff1872eaab82",
"WORKER_START_EMAIL": "d-debd127cab2345e789538131501ff416",
}
}
# EKS configs for Rl-worker
EKS_CLUSTER_ROLE_ARN = os.environ.get("EKS_CLUSTER_ROLE_ARN")
EKS_NODEGROUP_ROLE_ARN = os.environ.get("EKS_NODEGROUP_ROLE_ARN")
ENVIRONMENT = os.environ.get("ENVIRONMENT", "dev")
serializers.py
from django.contrib.auth import get_user_model
from rest_framework import serializers
from rest_auth.serializers import PasswordResetSerializer
class UserDetailsSerializer(serializers.ModelSerializer):
"""
Make username as a read_only field.
"""
class Meta:
model = get_user_model()
fields = (
"pk",
"email",
"username",
"first_name",
"last_name",
"password",
)
read_only_fields = ("email", "username")
class ProfileSerializer(UserDetailsSerializer):
"""
Serializer to update the user profile.
"""
affiliation = serializers.CharField(source="profile.affiliation")
github_url = serializers.URLField(
source="profile.github_url", allow_blank=True
)
google_scholar_url = serializers.URLField(
source="profile.google_scholar_url", allow_blank=True
)
linkedin_url = serializers.URLField(
source="profile.linkedin_url", allow_blank=True
)
class Meta(UserDetailsSerializer.Meta):
fields = (
"pk",
"email",
"username",
"first_name",
"last_name",
"affiliation",
"github_url",
"google_scholar_url",
"linkedin_url",
)
def update(self, instance, validated_data):
profile_data = validated_data.pop("profile", {})
affiliation = profile_data.get("affiliation")
github_url = profile_data.get("github_url")
google_scholar_url = profile_data.get("google_scholar_url")
linkedin_url = profile_data.get("linkedin_url")
instance = super(ProfileSerializer, self).update(
instance, validated_data
)
profile = instance.profile
if profile_data and affiliation:
profile.affiliation = affiliation
profile.github_url = github_url
profile.google_scholar_url = google_scholar_url
profile.linkedin_url = linkedin_url
profile.save()
return instance
class CustomPasswordResetSerializer(PasswordResetSerializer):
def get_email_options(self):
super().get_email_options()
return {
'subject_template_name': 'account/email/password_reset_key_subject.txt',
'email_template_name': 'account/password_reset_email.html',
'html_email_template_name': 'account/password_reset_email.html',
}
I've been stuck to this issue for about 1 week and I'm losing my confidence.
open source project is here, incase you want to check.
UPDATE - Now I'm getting another problem in which my email looks like this, I'm not getting the variable passed here.
enter image description here
And it should look like this
enter image description here
password_reset_email.html
{% load i18n %}{% blocktrans with site_name=current_site.name site_domain=current_site.domain %}Hello from {{ site_name }}!
You're receiving this e-mail because you or someone else has requested a password for your user account at {{ site_domain }}.
It can be safely ignored if you did not request a password reset. Click the link below to reset your password.{% endblocktrans %}
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
{% if username %}{% blocktrans %}In case you forgot, your username is {{ username }}.{% endblocktrans %}
{% endif %}{% blocktrans with site_name=current_site.name site_domain=current_site.domain %}Thank you for using {{ site_name }}!
{{ site_domain }}{% endblocktrans %}
UPDATE - I solved this issue by changing the extension from html to txt. It's strange I know but worked for me.
I was able to solve this answer by simply putting this logging code to settings.py file.
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
},
},
'handlers': {
'console': {
'level': 'NOTSET',
'class': 'logging.StreamHandler',
'formatter': 'verbose'
}
},
'loggers': {
'': {
'handlers': ['console'],
'level': 'NOTSET',
},
'django.request': {
'handlers': ['console'],
'propagate': False,
'level': 'ERROR'
}
}
}
The org in which I was contributing they were using docker file to setup the environment and they have edited the logging file according to them.
By adding that code to the settings file I was able to receive the error logs.