Configuring Google Cloud App Engine w Django - django

I'm following this tutorial
to deploy Django with Google Cloud. At the timestamp (13:39) he goes into settings.py in the Django project in VS Code and swaps some placeholders out for his own Google Cloud credentials. My settings.py however looks very different. The only thing in block caps that looks as if it might be a placeholder is "GOOGLE_CLOUD_PROJECT" and "SETTINGS_NAME". This is the part of the installation I can't get past because at the next step when I try to execute
python manage.py makemigrations
I get sent here:
else:
raise Exception("No local .env or GOOGLE_CLOUD_PROJECT detected. No secrets found.")
Hoping someone can glance over my settings.py and identify what I'm missing why that if block is going to Exception.
One thing to note: The top imports environ and google.cloud are not resolved. idk if that's got anything to do with it. This is how the file came out the can. I don't want to mess with it in case tshtf :D
settings.py
import io
import os
import environ
from google.cloud import secretmanager
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# [START gaestd_py_django_secret_config]
env = environ.Env(DEBUG=(bool, False))
env_file = os.path.join(BASE_DIR, ".env")
if os.path.isfile(env_file):
# Use a local secret file, if provided
env.read_env(env_file)
# [START_EXCLUDE]
elif os.getenv("TRAMPOLINE_CI", None):
# Create local settings if running with CI, for unit testing
placeholder = (
f"SECRET_KEY=a\n"
f"DATABASE_URL=sqlite://{os.path.join(BASE_DIR, 'db.sqlite3')}"
)
env.read_env(io.StringIO(placeholder))
# [END_EXCLUDE]
elif os.environ.get("GOOGLE_CLOUD_PROJECT", None):
# Pull secrets from Secret Manager
project_id = os.environ.get("GOOGLE_CLOUD_PROJECT")
client = secretmanager.SecretManagerServiceClient()
settings_name = os.environ.get("SETTINGS_NAME", "django_settings")
name = f"projects/{project_id}/secrets/{settings_name}/versions/latest"
payload = client.access_secret_version(name=name).payload.data.decode("UTF-8")
env.read_env(io.StringIO(payload))
else:
raise Exception("No local .env or GOOGLE_CLOUD_PROJECT detected. No secrets found.")
# [END gaestd_py_django_secret_config]
SECRET_KEY = env("SECRET_KEY")
# SECURITY WARNING: don't run with debug turned on in production!
# Change this to "False" when you are ready for production
DEBUG = True
# SECURITY WARNING: App Engine's security features ensure that it is safe to
# have ALLOWED_HOSTS = ['*'] when the app is deployed. If you deploy a Django
# app not on App Engine, make sure to set an appropriate host here.
ALLOWED_HOSTS = ["*"]
# Application definition
INSTALLED_APPS = [
"polls.apps.PollsConfig",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
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 = "mysite.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 = "mysite.wsgi.application"
# Database
# [START db_setup]
# [START gaestd_py_django_database_config]
# Use django-environ to parse the connection string
DATABASES = {"default": env.db()}
# If the flag as been set, configure to use proxy
if os.getenv("USE_CLOUD_SQL_AUTH_PROXY", None):
DATABASES["default"]["HOST"] = "127.0.0.1"
DATABASES["default"]["PORT"] = 5432
# [END gaestd_py_django_database_config]
# [END db_setup]
# Use a in-memory sqlite3 database when testing in CI systems
# TODO(glasnt) CHECK IF THIS IS REQUIRED because we're setting a val above
if os.getenv("TRAMPOLINE_CI", None):
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
}
}
# Password validation
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", # noqa: 501
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", # noqa: 501
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", # noqa: 501
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", # noqa: 501
},
]
# Internationalization
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
STATIC_ROOT = "static"
STATIC_URL = "/static/"
STATICFILES_DIRS = []
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

Django wants you to provide a SECRET_KEY. There are a couple of ways to provide such key, but one way is to create an .env file containing the SECRET_KEY in the same folder where the manage.py file is located.
A SECRET_KEY can be generated using the following code snippet (run it wherever you find convenient, but don't add the resulting key string to your settings.py file):
from django.core.management.utils import get_random_secret_key
get_random_secret_key()
Take the resulting output (it's a 50 character long string) and add it to the .env file with the following format:
SECRET_KEY="the-50-character-string-here"
You might potentially also have to replace BASE_DIR in the settings.py file with the following in order to properly load the .env file (note how the first row is out-commented).
#BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
BASE_DIR = os.getcwd()
You might run into more problems further down the road related to your database setup. Check out this and this SO question.
You can also consider checking out the Guide which is what the tutorial you're referring to is following.

Related

DJango admin is serving static files from /media instead of /static

When I run my django app in production mode (ie without DEBUG), my admin site tries to serve static files from "/media" instead of "/static", which causes 404s
This is what it's trying to serve.
GET https://<domain>/media/admin/css/base.css
But if I manually type in
https://<domain>/static/admin/css/base.css
It serves the static file correctly. So my "collectstatic" is working fine, but somehow the admin site is trying to serve from /media.
I don't understand what settings would cause this. Everything I search for related to this is from before django 1.4 where there was a specific setting for admin media url. Other than that I don't see anyone else having this issue.
I'm loosely following https://github.com/cookiecutter/cookiecutter-django and I'm on the latest version of django right now. I'm not sure what else to look for
A selection of settings (presumably irrelevant ones omitted)
#config/settings/base.py
DJANGO_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.sites",
"django.contrib.messages",
"django.contrib.staticfiles",
# "django.contrib.humanize", # Handy template tags
"django.forms",
]
# STATIC
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#static-root
STATIC_ROOT = str(ROOT_DIR / "staticfiles")
# https://docs.djangoproject.com/en/dev/ref/settings/#static-url
STATIC_URL = "/static/"
# https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
STATICFILES_DIRS = [str(APPS_DIR / "static")]
# https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders
STATICFILES_FINDERS = [
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
]
# MEDIA
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#media-root
MEDIA_ROOT = str(APPS_DIR / "media")
# https://docs.djangoproject.com/en/dev/ref/settings/#media-url
MEDIA_URL = "/media/"
# TEMPLATES
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#templates
TEMPLATES = [
{
# https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TEMPLATES-BACKEND
"BACKEND": "django.template.backends.django.DjangoTemplates",
# https://docs.djangoproject.com/en/dev/ref/settings/#dirs
"DIRS": [str(APPS_DIR / "templates")],
# https://docs.djangoproject.com/en/dev/ref/settings/#app-dirs
"APP_DIRS": True,
"OPTIONS": {
# https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.template.context_processors.i18n",
"django.template.context_processors.media",
"django.template.context_processors.static",
"django.template.context_processors.tz",
"django.contrib.messages.context_processors.messages",
"moment.users.context_processors.allauth_settings",
],
},
}
]
--
#config/settings/production.py
from .base import * # noqa
from .base import env
STATICFILES_STORAGE = "django.core.files.storage.FileSystemStorage"
COLLECTFAST_STRATEGY = "collectfast.strategies.filesystem.FileSystemStrategy"
ADMIN_URL = env("DJANGO_ADMIN_URL")
# Collectfast
# ------------------------------------------------------------------------------
# https://github.com/antonagestam/collectfast#installation
INSTALLED_APPS = ["collectfast"] + INSTALLED_APPS # noqa F405
Note that most of the static file settings are declared in my base.py, which is included when I run this in "debug" mode using config/settings/local.py. And that works fine. It's only in production mode that it's trying to serve the static files out of /media
It turns out this was caused by the https://github.com/antonagestam/collectfast provided by the cookiecutter template I was using. The default tried to use s3 as the static file location, and I configured it to use the local filesystem. There was probably something wrong with that configuration. I didn't look into it further. Removing the collectfast package worked

Django application running on top of Serverless + Lambda + API Gateway HTTP API is rewriting links to be prefixed with default

My Django Application (Largely REST Framework based) is currently producing URLs on the admin page that don't resolve. The expected result is that the Django Admin's login prompt submits the form with a POST to /admin/login. The resultant URL passed by as the form submission URL by Django is /$default/admin/login and that returns a 404 with the even more obtuse /$default/$default/admin/login/.
I'm presuming I have some sort of misconfiguration in either my Django configuration or serverless.yml.
As per the following serverless.yml I'm using API Gateway V2, Django through WSGI, and Lambda functions.
service: api
app: api
org: myapp
frameworkVersion: '3'
provider:
name: aws
runtime: python3.8
functions:
serve:
handler: wsgi_handler.handler
timeout: 20
environment:
DB_NAME: ${param:db_name}
DB_PASSWORD: ${param:db_password}
DB_USER: ${param:db_user}
DB_PORT: ${param:db_port}
DB_HOST: ${param:db_host}
events:
- httpApi: "*"
migration:
handler: migrate.handler
timeout: 60
environment:
DB_NAME: ${param:db_name}
DB_PASSWORD: ${param:db_password}
DB_USER: ${param:db_user}
DB_PORT: ${param:db_port}
DB_HOST: ${param:db_host}
custom:
wsgi:
app: myapp.wsgi.application
plugins:
- serverless-python-requirements
- serverless-wsgi
My URLs are pretty standard:
from django.contrib import admin
from django.urls import path, include
from rest_framework.schemas import get_schema_view
schema_view = get_schema_view(
title="MyApp",
description="MyApp Universal API",
version="1.0.0",
)
urlpatterns = [
path("admin/", admin.site.urls),
path("user/", include("myapp.core.urls"), name="user"),
path("openapi", schema_view, name="openapi-schema"),
]
My configuration is even more standard:
import os
from pathlib import Path
from dotenv import load_dotenv
load_dotenv()
# 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 = "not for you :)"
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
if 'CODESPACE_NAME' in os.environ:
codespace_name = os.getenv("CODESPACE_NAME")
codespace_domain = os.getenv("GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN")
CSRF_TRUSTED_ORIGINS = [f'https://{codespace_name}-8000.{codespace_domain}']
ROOT_URLCONF = "myapp.urls"
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
'rest_framework',
"myapp.core",
]
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",
]
X_FRAME_OPTIONS = "ALLOW-FROM preview.app.github.dev"
ROOT_URLCONF = "myapp.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "myapp" / "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 = "myapp.wsgi.application"
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('DB_NAME', 'neondb'),
'USER': os.environ.get('DB_USER', 'postgres'),
'PASSWORD': os.environ.get('DB_PASSWORD'),
'HOST': os.environ.get('DB_HOST', 'localhost'),
'PORT': os.environ.get('DB_PORT', 5432),
}
}
# 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/
STATICFILES_DIRS = [
BASE_DIR / "myapp" / "static",
]
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"
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3StaticStorage'
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = "myapp-django-static"
AUTH_USER_MODEL = 'core.User'
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticatedOrReadOnly',
)
}
As for the resultant error message:
Any help (or ideas) would be greatly appreciated!
I've tried modifying the path structure of the serverless.yml and have been trawling through the Django source code for any hints to no avail. Naturally I'd just like Django admin to work. As far as the rest of the app, it works fine as the API itself isn't self referential. Django just isn't returning the correct path.
To put it in brief, Django thinks that all of my routes are prefixed by /$default/ they are not. I'm looking for either a solution to force the path to sent by Django to be / or a fix for my Serverless configuration to mitigate this issue.
I managed to resolve this with a rather niché Django settings option: FORCE_SCRIPT_NAME
While this doesn't explain why it is resolving the path to /$default/ it does mitigate this issue.
If you're using this for a different use case than mine and your path is in a subdirectory (e.g the opposite issue to mine) then you would add your path in FORCE_SCRIPT_NAME instead.
See the link I've provided for more information.
Add the following to your app's settings.py, or any file you're using as your DJANGO_SETTINGS_MODULE.
# Force Django to resolve the URL to the root of the site
# This is required for API Gateway <- WSGI -> Django path resolution to work properly.
FORCE_SCRIPT_NAME = ""

400 Bad Request Django/React

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.

Cloudrun Django+Terraform / 404 error on app URL

I just followed this tutorial : https://github.com/GoogleCloudPlatform/serverless-expeditions/tree/main/cloud-run-django-terraform
I've done :
gcloud builds submit --config cloudbuild-migrate.yaml
terraform apply -var project=$PROJECT_ID
My database was created. Service was pushed online well and I've got a service_url.
When I access it, it shows a 404 error. Even if try to access the /admin page, it just returns a 500 error with no explanation in the log journal (or I didn't find it).
When I try to runserver on localhost with sql_cloud_proxy, Django works perfectly. It's just a Django basic project showing hello on homepage.
I don't get it.
Here's my settings.py file :
import io
import os
from pathlib import Path
import environ
import google.auth
from google.cloud import secretmanager
BASE_DIR = Path(__file__).resolve().parent.parent
env = environ.Env(DEBUG=(bool, False))
env_file = os.path.join(BASE_DIR, ".env")
# Attempt to load the Project ID into the environment, safely failing on error.
try:
_, os.environ["GOOGLE_CLOUD_PROJECT"] = google.auth.default()
except google.auth.exceptions.DefaultCredentialsError:
pass
if os.path.isfile(env_file):
# Use a local secret file, if provided
env.read_env(env_file)
elif os.environ.get("GOOGLE_CLOUD_PROJECT", None):
# Pull secrets from Secret Manager
project_id = os.environ.get("GOOGLE_CLOUD_PROJECT")
client = secretmanager.SecretManagerServiceClient()
settings_name = os.environ.get("SETTINGS_NAME", "django_settings")
name = f"projects/{project_id}/secrets/{settings_name}/versions/latest"
payload = client.access_secret_version(name=name).payload.data.decode("UTF-8")
env.read_env(io.StringIO(payload))
else:
raise Exception("No local .env or GOOGLE_CLOUD_PROJECT detected. No secrets found.")
SECRET_KEY = env("SECRET_KEY")
# DEBUG = env("DEBUG")
DEBUG = True
ALLOWED_HOSTS = ["*"]
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"gadsapimonitor",
"storages",
]
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 = "gadsapimonitor.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 = "gadsapimonitor.wsgi.application"
# Use django-environ to parse DATABASE_URL from secrets
DATABASES = {"default": env.db()}
# If using Cloud SQL Auth Proxy, change the database values accordingly.
if os.environ.get("USE_CLOUD_SQL_AUTH_PROXY"):
DATABASES["default"]["HOST"] = "127.0.0.1"
DATABASES["default"]["PORT"] = 5432
else:
DATABASES["default"]["HOST"] = "127.0.0.1"
DATABASES["default"]["PORT"] = 5432
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 = "fr-fr"
TIME_ZONE = "UTC"
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_ROOT = "/static/"
STATIC_URL = "/static/"
# Define static storage via django-storages[google]
if env("GS_BUCKET_NAME"):
GS_BUCKET_NAME = env("GS_BUCKET_NAME")
STATICFILES_DIRS = []
DEFAULT_FILE_STORAGE = "storages.backends.gcloud.GoogleCloudStorage"
STATICFILES_STORAGE = "storages.backends.gcloud.GoogleCloudStorage"
GS_DEFAULT_ACL = "publicRead"
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
My Dockerfile :
# Use an official lightweight Python image.
# https://hub.docker.com/_/python
FROM python:3.9-slim
ENV APP_HOME /app
WORKDIR $APP_HOME
# Install dependencies.
COPY requirements.txt .
RUN pip install -r requirements.txt
# Copy local code to the container image.
COPY . .
# Service must listen to $PORT environment variable.
# This default value facilitates local development.
ENV PORT 8080
# Setting this ensures print statements and log messages
# promptly appear in Cloud Logging.
ENV PYTHONUNBUFFERED TRUE
# Run the web service on container startup. Here we use the gunicorn
# webserver, with one worker process and 8 threads.
# For environments with multiple CPU cores, increase the number of workers
# to be equal to the cores available.
CMD exec gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 myapp.wsgi:application
I've tried to set DEBUG=True to show something but nothing changed.
Is someone has an idea to fix this issue ?
Many thanks,
EDIT : Log
{
httpRequest: {10}
insertId: "61bd16c6000351727a95b33c"
labels: {
instanceId: "00bf4bf02de1a8b1de1bec9253140c16ac133ee11a6264fd4b1ce063dee5b680b3e567f87e6e1ec1a40e92314275ca0dac93e25dc02cded8677918"
}
logName: "projects/gaxxxxxxxtor-xxxx420/logs/run.googleapis.com%2Frequests"
receiveTimestamp: "2021-12-17T23:01:26.220970335Z"
resource: {
labels: {
configuration_name: "gaxxxxxxxtor-xxxx420"
location: "europe-west4"
project_id: "gaxxxxxxxtor-xxxx420"
revision_name: "gaxxxxxxxtor-xxxx420-kw9ld"
service_name: "gaxxxxxxxtor-xxxx420"
}
type: "cloud_run_revision"
}
severity: "ERROR"
timestamp: "2021-12-17T23:01:26.217458Z"
trace: "projects/gaxxxxxxxtor-xxxx420/traces/3e655015a967bfe8903db0ef5d1cfc7f"
}

Django programming: cannot cast time without time zone to timestamp

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