From e7cc2878364fcfd94faac9acbfed36e10410fa55 Mon Sep 17 00:00:00 2001
From: Jennifer Richards <jennifer@staff.ietf.org>
Date: Wed, 17 May 2023 17:42:12 -0300
Subject: [PATCH 1/5] chore: Update requirements.txt for Django 4.1

---
 requirements.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/requirements.txt b/requirements.txt
index 1c39cf4ec..e05b31200 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,7 +11,7 @@ coverage>=4.5.4,<5.0    # Coverage 5.x moves from a json database to SQLite.  Mo
 decorator>=5.1.1
 types-decorator>=5.1.1
 defusedxml>=0.7.1    # for TastyPie when using xml; not a declared dependency
-Django<4.1
+Django<4.2
 django-analytical>=3.1.0
 django-bootstrap5>=21.3
 django-celery-beat>=2.3.0

From c26c9c71e4b9f0c4e62cf6929455b5db84b08f44 Mon Sep 17 00:00:00 2001
From: Jennifer Richards <jennifer@staff.ietf.org>
Date: Wed, 17 May 2023 17:42:51 -0300
Subject: [PATCH 2/5] chore: Switch to PyMemcacheCache backend

---
 ietf/settings.py | 4 ++--
 requirements.txt | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/ietf/settings.py b/ietf/settings.py
index 3fd08ffa4..e7011abf9 100644
--- a/ietf/settings.py
+++ b/ietf/settings.py
@@ -716,13 +716,13 @@ CACHE_MIDDLEWARE_KEY_PREFIX = ''
 # This setting is possibly overridden further down, after the import of settings_local
 CACHES = {
     'default': {
-        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
+        'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
         'LOCATION': '127.0.0.1:11211',
         'VERSION': __version__,
         'KEY_PREFIX': 'ietf:dt',
     },
     'sessions': {
-        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
+        'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
         'LOCATION': '127.0.0.1:11211',
         # No release-specific VERSION setting.
         'KEY_PREFIX': 'ietf:dt',
diff --git a/requirements.txt b/requirements.txt
index e05b31200..75aca6574 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -56,7 +56,7 @@ pyquery>=1.4.3
 python-dateutil>=2.8.2
 types-python-dateutil>=2.8.2
 python-magic==0.4.18    # Versions beyond the yanked .19 and .20 introduce form failures
-python-memcached>=1.59    # for django.core.cache.backends.memcached
+pymemcache>=4.0.0  # for django.core.cache.backends.memcached.PyMemcacheCache 
 python-mimeparse>=1.6    # from TastyPie
 pytz==2022.2.1   # Pinned as changes need to be vetted for their effect on Meeting fields
 requests>=2.27.1

From 3c2def34f91c430beb7846b8b20395b39ebacdbb Mon Sep 17 00:00:00 2001
From: Jennifer Richards <jennifer@staff.ietf.org>
Date: Wed, 17 May 2023 17:55:02 -0300
Subject: [PATCH 3/5] chore: Update
 django-cookie-delete-with-all-settings.patch

---
 patch/django-cookie-delete-with-all-settings.patch | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/patch/django-cookie-delete-with-all-settings.patch b/patch/django-cookie-delete-with-all-settings.patch
index 9b327928d..8c194ae33 100644
--- a/patch/django-cookie-delete-with-all-settings.patch
+++ b/patch/django-cookie-delete-with-all-settings.patch
@@ -11,7 +11,7 @@
  
 --- django/http/response.py.orig	2020-08-13 11:16:04.060627793 +0200
 +++ django/http/response.py	2020-08-13 11:54:03.482476973 +0200
-@@ -261,20 +261,28 @@
+@@ -279,20 +279,28 @@
          value = signing.get_cookie_signer(salt=key + salt).sign(value)
          return self.set_cookie(key, value, **kwargs)
 

From 47e2b0b0278d7242a7e8b9ae4ab31b13056e90e1 Mon Sep 17 00:00:00 2001
From: Jennifer Richards <jennifer@staff.ietf.org>
Date: Wed, 17 May 2023 19:53:02 -0300
Subject: [PATCH 4/5] fix: Prevent use of FK relation before review request is
 saved

---
 ietf/review/policies.py | 9 ++++++---
 ietf/review/utils.py    | 3 ++-
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/ietf/review/policies.py b/ietf/review/policies.py
index e834891f7..fe6519a5e 100644
--- a/ietf/review/policies.py
+++ b/ietf/review/policies.py
@@ -183,9 +183,12 @@ class AbstractReviewerQueuePolicy:
             role__group=review_req.team
         ).exclude( person_id__in=rejecting_reviewer_ids )
 
-        one_assignment = (review_req.reviewassignment_set
-                          .exclude(state__slug__in=('rejected', 'no-response'))
-                          .first())
+        one_assignment = None
+        if review_req.pk is not None:
+            # cannot use reviewassignment_set relation until review_req has been created
+            one_assignment = (review_req.reviewassignment_set
+                              .exclude(state__slug__in=('rejected', 'no-response'))
+                              .first())
         if one_assignment:
             field.initial = one_assignment.reviewer_id
 
diff --git a/ietf/review/utils.py b/ietf/review/utils.py
index 1e9a237b5..2b9979c95 100644
--- a/ietf/review/utils.py
+++ b/ietf/review/utils.py
@@ -382,7 +382,8 @@ def assign_review_request_to_reviewer(request, review_req, reviewer, add_skip=Fa
     # with a different view on a ReviewAssignment.
     log.assertion('reviewer is not None')
 
-    if review_req.reviewassignment_set.filter(reviewer=reviewer).exists():
+    # cannot reference reviewassignment_set relation until pk exists
+    if review_req.pk is not None and review_req.reviewassignment_set.filter(reviewer=reviewer).exists():
         return
 
     # Note that assigning a review no longer unassigns other reviews

From 55fb50217947f742e7981bd94a7ac247c0aa3287 Mon Sep 17 00:00:00 2001
From: Jennifer Richards <jennifer@staff.ietf.org>
Date: Thu, 18 May 2023 10:42:01 -0300
Subject: [PATCH 5/5] test: Iterate over template.nodelist in
 apply_template_test

---
 ietf/utils/tests.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ietf/utils/tests.py b/ietf/utils/tests.py
index 69c16be6d..fe715b14d 100644
--- a/ietf/utils/tests.py
+++ b/ietf/utils/tests.py
@@ -209,7 +209,7 @@ class TemplateChecksTestCase(TestCase):
         errors = []
         for path, template in self.templates.items():
             origin = str(template.origin).replace(settings.BASE_DIR, '')
-            for node in template:
+            for node in template.nodelist:
                 for child in node.get_nodes_by_type(node_type):
                     errors += func(child, origin, *args, **kwargs)
         if errors: