From 1aa18a6406ecdc9cf87afa6e08ed3be3f1b2d0ba Mon Sep 17 00:00:00 2001 From: David del Real Sifuentes Date: Wed, 7 Jan 2026 22:40:44 +0000 Subject: [PATCH 1/8] chore: updating Django and python versions in requirements, CI-CD/Nox files. b/470283288 Updated Django version to 6.0.1. Updated required python version to 3.12 (minimum version required by Django 6.0.1) --- kubernetes_engine/django_tutorial/requirements.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kubernetes_engine/django_tutorial/requirements.txt b/kubernetes_engine/django_tutorial/requirements.txt index 1ef339da5ba..305133d86ad 100644 --- a/kubernetes_engine/django_tutorial/requirements.txt +++ b/kubernetes_engine/django_tutorial/requirements.txt @@ -1,5 +1,4 @@ -Django==5.2.9; python_version >= "3.10" -Django==4.2.24; python_version >= "3.8" and python_version < "3.10" +Django==6.0.1; python_version >= "3.12" # Uncomment the mysqlclient requirement if you are using MySQL rather than # PostgreSQL. You must also have a MySQL client installed in that case. #mysqlclient==1.4.1 From 98679829ee2d8ed48b6d9dbe2f4638267c65dc10 Mon Sep 17 00:00:00 2001 From: David del Real Sifuentes Date: Thu, 8 Jan 2026 16:28:47 +0000 Subject: [PATCH 2/8] chore: Updated requirements for App Engine Django Flexible Environment b/470283244 - Updated Django and python version in requirements file. - Updated and added missing attributes for frameworks's execution. --- appengine/flexible/hello_world_django/noxfile_config.py | 2 +- appengine/flexible/hello_world_django/project_name/settings.py | 2 ++ appengine/flexible/hello_world_django/project_name/urls.py | 2 +- appengine/flexible/hello_world_django/requirements.txt | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/appengine/flexible/hello_world_django/noxfile_config.py b/appengine/flexible/hello_world_django/noxfile_config.py index 196376e7023..692b834f789 100644 --- a/appengine/flexible/hello_world_django/noxfile_config.py +++ b/appengine/flexible/hello_world_django/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7"], + "ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11"], # Old samples are opted out of enforcing Python type hints # All new samples should feature them "enforce_type_hints": False, diff --git a/appengine/flexible/hello_world_django/project_name/settings.py b/appengine/flexible/hello_world_django/project_name/settings.py index f8b93099d56..bd094b5f576 100644 --- a/appengine/flexible/hello_world_django/project_name/settings.py +++ b/appengine/flexible/hello_world_django/project_name/settings.py @@ -114,3 +114,5 @@ # https://docs.djangoproject.com/en/stable/howto/static-files/ STATIC_URL = "/static/" + +STATIC_ROOT = os.path.join(BASE_DIR, 'static') diff --git a/appengine/flexible/hello_world_django/project_name/urls.py b/appengine/flexible/hello_world_django/project_name/urls.py index 9a393bb42d2..5928814711e 100644 --- a/appengine/flexible/hello_world_django/project_name/urls.py +++ b/appengine/flexible/hello_world_django/project_name/urls.py @@ -19,6 +19,6 @@ urlpatterns = [ - path("admin/", include(admin.site.urls)), + path("admin/", admin.site.urls), path("", helloworld.views.index), ] diff --git a/appengine/flexible/hello_world_django/requirements.txt b/appengine/flexible/hello_world_django/requirements.txt index 435ef2cb8ee..a7f029a554d 100644 --- a/appengine/flexible/hello_world_django/requirements.txt +++ b/appengine/flexible/hello_world_django/requirements.txt @@ -1,2 +1,2 @@ -Django==5.2.9 +Django==6.0.1; python_version >= "3.12" gunicorn==23.0.0 From 4a56d72a28fcf5d825e9e560818707d6057aa44c Mon Sep 17 00:00:00 2001 From: David del Real Sifuentes Date: Fri, 9 Jan 2026 21:01:55 +0000 Subject: [PATCH 3/8] chore: Updated requirements for Run Django b/470283502 - Updated Django and python version in requirements and nox files. --- run/django/noxfile_config.py | 2 +- run/django/requirements.txt | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/run/django/noxfile_config.py b/run/django/noxfile_config.py index e928b32a2d2..c8a36780cd0 100644 --- a/run/django/noxfile_config.py +++ b/run/django/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.6", "3.7", "3.8"], + "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11"], # Old samples are opted out of enforcing Python type hints # All new samples should feature the "enforce_type_hints": True, diff --git a/run/django/requirements.txt b/run/django/requirements.txt index 92897c3072e..1f87eae2dbe 100644 --- a/run/django/requirements.txt +++ b/run/django/requirements.txt @@ -1,5 +1,4 @@ -Django==5.2.5; python_version >= "3.10" -Django==4.2.24; python_version >= "3.8" and python_version < "3.10" +Django==6.0.1; python_version >= "3.12" django-storages[google]==1.14.6 django-environ==0.12.0 psycopg2-binary==2.9.10 From f47239d0e657f3d8269298c4da2ce35d695c4f6a Mon Sep 17 00:00:00 2001 From: David del Real Sifuentes Date: Mon, 12 Jan 2026 18:01:02 +0000 Subject: [PATCH 4/8] chore: Update requirements for Django Cloud SQL - Updated requirements and nox files for latest Django version. --- .../flexible/django_cloudsql/noxfile_config.py | 2 +- .../flexible/django_cloudsql/requirements.txt | 4 ++-- appengine/flexible/hello_world_django/app.yaml | 2 +- .../hello_world_django/project_name/urls.py | 2 +- kubernetes_engine/django_tutorial/requirements.txt | 2 +- run/django/e2e_test_setup.yaml | 1 + run/django/mysite/settings.py | 14 +++++++++++++- run/django/noxfile_config.py | 2 +- run/django/requirements.txt | 2 +- 9 files changed, 22 insertions(+), 9 deletions(-) diff --git a/appengine/flexible/django_cloudsql/noxfile_config.py b/appengine/flexible/django_cloudsql/noxfile_config.py index 30010ba672d..60e19bd8a96 100644 --- a/appengine/flexible/django_cloudsql/noxfile_config.py +++ b/appengine/flexible/django_cloudsql/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.7", "3.8", "3.10", "3.12", "3.13"], + "ignored_versions": ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11"], # An envvar key for determining the project id to use. Change it # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a # build specific Cloud project. You can also use your own string diff --git a/appengine/flexible/django_cloudsql/requirements.txt b/appengine/flexible/django_cloudsql/requirements.txt index e309f97d5bc..da90b09edaa 100644 --- a/appengine/flexible/django_cloudsql/requirements.txt +++ b/appengine/flexible/django_cloudsql/requirements.txt @@ -1,6 +1,6 @@ -Django==5.2.9 +Django==6.0.1; python_version >= "3.12" gunicorn==23.0.0 -psycopg2-binary==2.9.10 +psycopg2-binary==2.9.11 django-environ==0.12.0 google-cloud-secret-manager==2.21.1 django-storages[google]==1.14.6 diff --git a/appengine/flexible/hello_world_django/app.yaml b/appengine/flexible/hello_world_django/app.yaml index 62b74a9c27e..85096c4adc4 100644 --- a/appengine/flexible/hello_world_django/app.yaml +++ b/appengine/flexible/hello_world_django/app.yaml @@ -17,4 +17,4 @@ env: flex entrypoint: gunicorn -b :$PORT project_name.wsgi runtime_config: - python_version: 3 + operating_system: "ubuntu24" diff --git a/appengine/flexible/hello_world_django/project_name/urls.py b/appengine/flexible/hello_world_django/project_name/urls.py index 5928814711e..7d3a1e0f315 100644 --- a/appengine/flexible/hello_world_django/project_name/urls.py +++ b/appengine/flexible/hello_world_django/project_name/urls.py @@ -13,7 +13,7 @@ # limitations under the License. from django.contrib import admin -from django.urls import include, path +from django.urls import path import helloworld.views diff --git a/kubernetes_engine/django_tutorial/requirements.txt b/kubernetes_engine/django_tutorial/requirements.txt index 305133d86ad..df3b50126a0 100644 --- a/kubernetes_engine/django_tutorial/requirements.txt +++ b/kubernetes_engine/django_tutorial/requirements.txt @@ -6,4 +6,4 @@ wheel==0.40.0 gunicorn==23.0.0; python_version > '3.0' gunicorn==23.0.0; python_version < '3.0' # psycopg2==2.8.4 # uncomment if you prefer to build from source -psycopg2-binary==2.9.10 +psycopg2-binary==2.9.11 diff --git a/run/django/e2e_test_setup.yaml b/run/django/e2e_test_setup.yaml index 6ee69ce3f9f..c1aacb2911e 100644 --- a/run/django/e2e_test_setup.yaml +++ b/run/django/e2e_test_setup.yaml @@ -45,6 +45,7 @@ steps: ./retry.sh "gsutil mb \ -l ${_REGION} \ -p ${PROJECT_ID} \ + -b off \ gs://${_STORAGE_BUCKET}" - id: "IAM and Secrets" diff --git a/run/django/mysite/settings.py b/run/django/mysite/settings.py index a57c07ede72..506435c031a 100644 --- a/run/django/mysite/settings.py +++ b/run/django/mysite/settings.py @@ -174,12 +174,24 @@ STORAGES = { "default": { "BACKEND": "storages.backends.gcloud.GoogleCloudStorage", + "options": { + "bucket_name": GS_BUCKET_NAME, + "querystring_auth": False, + "default_acl": None, + "expiration": 300, + }, }, "staticfiles": { "BACKEND": "storages.backends.gcloud.GoogleCloudStorage", + "options": { + "bucket_name": GS_BUCKET_NAME, + "querystring_auth": False, + "default_acl": None, + "expiration": 300, + }, }, } -GS_DEFAULT_ACL = "publicRead" +GS_DEFAULT_ACL = None # [END cloudrun_django_static_config] # Default primary key field type diff --git a/run/django/noxfile_config.py b/run/django/noxfile_config.py index c8a36780cd0..6bdd6330695 100644 --- a/run/django/noxfile_config.py +++ b/run/django/noxfile_config.py @@ -22,7 +22,7 @@ TEST_CONFIG_OVERRIDE = { # You can opt out from the test for specific Python versions. - "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11"], + "ignored_versions": ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.14"], # Old samples are opted out of enforcing Python type hints # All new samples should feature the "enforce_type_hints": True, diff --git a/run/django/requirements.txt b/run/django/requirements.txt index 1f87eae2dbe..ee675495a97 100644 --- a/run/django/requirements.txt +++ b/run/django/requirements.txt @@ -1,6 +1,6 @@ Django==6.0.1; python_version >= "3.12" django-storages[google]==1.14.6 django-environ==0.12.0 -psycopg2-binary==2.9.10 +psycopg2-binary==2.9.11 gunicorn==23.0.0 google-cloud-secret-manager==2.21.1 From 1c20c68c43b897b1fbe5cd4a942963a43abe0a41 Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Wed, 28 Jan 2026 09:39:23 +1100 Subject: [PATCH 5/8] fork of 13742 as at 64e4e31b From 4cedf2ff58a9dd80cf0c3c15b37406545ba62e20 Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Wed, 28 Jan 2026 09:40:35 +1100 Subject: [PATCH 6/8] temporarily disable cleanup - to allow deployed service inspection --- run/django/e2e_test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/run/django/e2e_test.py b/run/django/e2e_test.py index f099f2e43fe..d1123e544fc 100644 --- a/run/django/e2e_test.py +++ b/run/django/e2e_test.py @@ -119,7 +119,7 @@ def deployed_service() -> str: yield SERVICE # Cleanup - + """ substitutions = [ f"_VERSION={SUFFIX}," f"_SERVICE={SERVICE}," @@ -142,6 +142,7 @@ def deployed_service() -> str: ] + substitutions ) + """ @pytest.fixture From 5fe35c2f1fbb3ebeeed349194f19988c7d4721f5 Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Wed, 28 Jan 2026 11:25:26 +1100 Subject: [PATCH 7/8] Enabled signed URLs --- run/django/mysite/settings.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/run/django/mysite/settings.py b/run/django/mysite/settings.py index 506435c031a..9cb1a392ec2 100644 --- a/run/django/mysite/settings.py +++ b/run/django/mysite/settings.py @@ -177,7 +177,7 @@ "options": { "bucket_name": GS_BUCKET_NAME, "querystring_auth": False, - "default_acl": None, + "default_acl": True, "expiration": 300, }, }, @@ -185,13 +185,14 @@ "BACKEND": "storages.backends.gcloud.GoogleCloudStorage", "options": { "bucket_name": GS_BUCKET_NAME, - "querystring_auth": False, + "querystring_auth": True, "default_acl": None, "expiration": 300, }, }, } GS_DEFAULT_ACL = None +GS_IAM_SIGN_BLOB = True # [END cloudrun_django_static_config] # Default primary key field type From a1ec42ce086c878140c20156d3d73945dad9d63f Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Wed, 28 Jan 2026 11:38:14 +1100 Subject: [PATCH 8/8] create a dedicated service account with token creator permissions token required for django-storages blob signing --- run/django/e2e_test_setup.yaml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/run/django/e2e_test_setup.yaml b/run/django/e2e_test_setup.yaml index c1aacb2911e..dde14069963 100644 --- a/run/django/e2e_test_setup.yaml +++ b/run/django/e2e_test_setup.yaml @@ -58,14 +58,23 @@ steps: GS_BUCKET_NAME=${_STORAGE_BUCKET} SECRET_KEY=$(cat /dev/urandom | LC_ALL=C tr -dc '[:alpha:]' | fold -w 30 | head -n1)" > ${_SECRET_SETTINGS_NAME} - sa_email=$(gcloud projects list --filter "name=${PROJECT_ID}" --format "value(projectNumber)")-compute@developer.gserviceaccount.com + ./retry.sh "gcloud iam service-accounts create ${_SERVICE_ACCOUNT_NAME}" + + ./retry.sh "gcloud projects add-iam-policy-binding ${PROJECT_ID} \ + --member="serviceAccount:${_SERVICE_ACCOUNT_EMAIL} \ + --role=rroles/iam.serviceAccountTokenCreator" + + ./retry.sh "gcloud iam add-iam-policy-binding ${_SECRET_SETTINGS_NAME} \ + --member serviceAccount:${_SERVICE_ACCOUNT_EMAIL} \ + --role roles/secretmanager.secretAccessor \ + --project ${PROJECT_ID}" ./retry.sh "gcloud secrets create ${_SECRET_SETTINGS_NAME} \ --project $PROJECT_ID \ --data-file=${_SECRET_SETTINGS_NAME}" ./retry.sh "gcloud secrets add-iam-policy-binding ${_SECRET_SETTINGS_NAME} \ - --member serviceAccount:${sa_email} \ + --member serviceAccount:${_SERVICE_ACCOUNT_EMAIL} \ --role roles/secretmanager.secretAccessor \ --project ${PROJECT_ID}" @@ -94,6 +103,7 @@ steps: --set-cloudsql-instances ${_CLOUD_SQL_CONNECTION_NAME} \ --set-env-vars SETTINGS_NAME=${_SECRET_SETTINGS_NAME} \ --command migrate \ + --service-account=${_SERVICE_ACCOUNT_EMAIL} \ --execute-now --wait" - id: "Create Superuser" @@ -110,6 +120,7 @@ steps: --set-env-vars SETTINGS_NAME=${_SECRET_SETTINGS_NAME} \ --set-env-vars DJANGO_SUPERUSER_PASSWORD=${_ADMIN_PASSWORD} \ --set-env-vars DJANGO_SUPERUSER_EMAIL=${_ADMIN_EMAIL} \ + --service-account=${_SERVICE_ACCOUNT_EMAIL} \ --execute-now --wait" - id: "Deploy to Cloud Run" @@ -124,6 +135,7 @@ steps: --no-allow-unauthenticated \ --region ${_REGION} \ --set-cloudsql-instances ${_CLOUD_SQL_CONNECTION_NAME} \ + --service-account=${_SERVICE_ACCOUNT_EMAIL} \ --set-env-vars SETTINGS_NAME=${_SECRET_SETTINGS_NAME}" images: @@ -149,4 +161,5 @@ substitutions: _DB_PASS: password1234 _ADMIN_PASSWORD: superpass _ADMIN_EMAIL: example@noop.com - + _SERVICE_ACCOUNT_NAME: django-sa-${_VERSION} + _SERVICE_ACCOUNT_EMAIL: ${_SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com