From a6efba2e70d7399dd5f2ec84238b57498e16418e Mon Sep 17 00:00:00 2001
From: ffont
Date: Tue, 11 Feb 2025 18:03:11 +0100
Subject: [PATCH 1/5] Make registration modal properly init ui elements in
contaier
---
freesound/static/bw-frontend/src/components/loginModals.js | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/freesound/static/bw-frontend/src/components/loginModals.js b/freesound/static/bw-frontend/src/components/loginModals.js
index ed6e1800c..a95b5d0d4 100644
--- a/freesound/static/bw-frontend/src/components/loginModals.js
+++ b/freesound/static/bw-frontend/src/components/loginModals.js
@@ -1,7 +1,8 @@
import { showToast } from './toast';
import serialize from '../utils/formSerializer'
-import { activateModal, dismissModal, handleGenericModalWithForm } from "../components/modal";
+import { activateModal, dismissModal, handleGenericModalWithForm } from "./modal";
import { addRecaptchaScriptTagToMainHead } from '../utils/recaptchaDynamicReload'
+import { initializeStuffInContainer } from '../utils/initHelper';
const checkUsernameAvailability = (username, baseURL, callback) => {
const req = new XMLHttpRequest();
@@ -42,6 +43,9 @@ const customProblemsLoggingInSubmit = (event) => {
};
const initRegistrationForm = (registrationForm) => {
+
+ // Initialize UI elements
+ initializeStuffInContainer(registrationForm, false, false);
// Bind click actions on links to move to other login modals
initLoginAndRegistrationModalLinks('registerModal');
From cd587d4a2c0890785c062adb77c9eb6118ea1a71 Mon Sep 17 00:00:00 2001
From: ffont
Date: Tue, 11 Feb 2025 18:03:44 +0100
Subject: [PATCH 2/5] Make sure all djago forms use .as_p rendering method
---
.../bw-frontend/styles/molecules/forms.scss | 16 ++++++++++++++++
templates/accounts/delete.html | 2 +-
templates/accounts/edit_email_settings.html | 2 +-
templates/accounts/login.html | 8 ++++----
templates/accounts/modal_bulk_describe.html | 6 +++---
templates/accounts/modal_login.html | 6 +++---
templates/accounts/modal_login_problems.html | 6 +++---
templates/accounts/modal_registration.html | 6 +++---
templates/accounts/password_reset_confirm.html | 6 +++---
templates/bookmarks/modal_bookmark_sound.html | 4 ++--
.../bookmarks/modal_edit_bookmark_category.html | 6 +++---
templates/donations/donate.html | 4 ++--
templates/forum/moderate.html | 6 +++---
templates/moderation/modal_annotations.html | 4 ++--
templates/moderation/ticket.html | 6 +++---
templates/molecules/form.html | 0
templates/sounds/modal_flag_sound.html | 6 +++---
templates/support/contact.html | 6 +++---
templates/wiki/edit.html | 6 +++---
19 files changed, 61 insertions(+), 45 deletions(-)
create mode 100644 templates/molecules/form.html
diff --git a/freesound/static/bw-frontend/styles/molecules/forms.scss b/freesound/static/bw-frontend/styles/molecules/forms.scss
index 3478385c2..2c876eb9c 100644
--- a/freesound/static/bw-frontend/styles/molecules/forms.scss
+++ b/freesound/static/bw-frontend/styles/molecules/forms.scss
@@ -108,4 +108,20 @@
label {
color: $navy-grey;
}
+}
+
+.bw-form-less-spacing {
+
+ p {
+ margin-top: 0!important;
+ }
+
+ input,
+ textarea {
+ &:not(.tags-input):not(.mapboxgl-ctrl-geocoder--input) {
+ margin-top: 10px!important;
+ margin-bottom: 15px!important;
+ }
+ }
+
}
\ No newline at end of file
diff --git a/templates/accounts/delete.html b/templates/accounts/delete.html
index 316a432ab..50f32592c 100644
--- a/templates/accounts/delete.html
+++ b/templates/accounts/delete.html
@@ -15,7 +15,7 @@ Delete account
diff --git a/templates/accounts/edit_email_settings.html b/templates/accounts/edit_email_settings.html
index 5e2ff40d6..9a32d97c2 100644
--- a/templates/accounts/edit_email_settings.html
+++ b/templates/accounts/edit_email_settings.html
@@ -15,7 +15,7 @@ Email notifications
Send me an email when:
diff --git a/templates/accounts/login.html b/templates/accounts/login.html
index 633bed1e5..100eed734 100644
--- a/templates/accounts/login.html
+++ b/templates/accounts/login.html
@@ -7,11 +7,11 @@
{% block page-content %}
-
diff --git a/templates/accounts/modal_bulk_describe.html b/templates/accounts/modal_bulk_describe.html
index 1eb382771..8821cac61 100644
--- a/templates/accounts/modal_bulk_describe.html
+++ b/templates/accounts/modal_bulk_describe.html
@@ -17,10 +17,10 @@
Describe sounds using data file
these instructions.
Upload your data file using the form below:
-
diff --git a/templates/accounts/modal_login.html b/templates/accounts/modal_login.html
index a6e950a69..bb08ef19b 100644
--- a/templates/accounts/modal_login.html
+++ b/templates/accounts/modal_login.html
@@ -7,10 +7,10 @@
Log in to Freesound
-
diff --git a/templates/accounts/modal_login_problems.html b/templates/accounts/modal_login_problems.html
index c75e15005..2abb56a59 100644
--- a/templates/accounts/modal_login_problems.html
+++ b/templates/accounts/modal_login_problems.html
@@ -12,9 +12,9 @@ Problems logging in?
Enter your email or username below and we'll send you a link to help you login into your account.
-
diff --git a/templates/accounts/modal_registration.html b/templates/accounts/modal_registration.html
index b003645af..03a876647 100644
--- a/templates/accounts/modal_registration.html
+++ b/templates/accounts/modal_registration.html
@@ -7,9 +7,9 @@
Join Freesound
-
diff --git a/templates/accounts/password_reset_confirm.html b/templates/accounts/password_reset_confirm.html
index cf26869ac..0b662c332 100644
--- a/templates/accounts/password_reset_confirm.html
+++ b/templates/accounts/password_reset_confirm.html
@@ -8,9 +8,9 @@
-
diff --git a/templates/bookmarks/modal_bookmark_sound.html b/templates/bookmarks/modal_bookmark_sound.html
index 71f1200e7..4b27aebfc 100644
--- a/templates/bookmarks/modal_bookmark_sound.html
+++ b/templates/bookmarks/modal_bookmark_sound.html
@@ -43,8 +43,8 @@
Bookmark this sound
{% endif %}
{% endif %}
-
diff --git a/templates/bookmarks/modal_edit_bookmark_category.html b/templates/bookmarks/modal_edit_bookmark_category.html
index 120ea6663..585a2108a 100644
--- a/templates/bookmarks/modal_edit_bookmark_category.html
+++ b/templates/bookmarks/modal_edit_bookmark_category.html
@@ -9,9 +9,9 @@
Edit bookmark Category
-
diff --git a/templates/donations/donate.html b/templates/donations/donate.html
index 60ddd1d8e..41c9c3243 100644
--- a/templates/donations/donate.html
+++ b/templates/donations/donate.html
@@ -41,9 +41,9 @@
Why should I donate to Freesound?
-
diff --git a/templates/forum/moderate.html b/templates/forum/moderate.html
index 2cf66d346..b9c3d4a2b 100644
--- a/templates/forum/moderate.html
+++ b/templates/forum/moderate.html
@@ -24,9 +24,9 @@
-
diff --git a/templates/moderation/modal_annotations.html b/templates/moderation/modal_annotations.html
index 9f9c292a9..9290cf82d 100644
--- a/templates/moderation/modal_annotations.html
+++ b/templates/moderation/modal_annotations.html
@@ -44,8 +44,8 @@ Annotations ({{ annotations|length }})
{% endfor %}
-
diff --git a/templates/moderation/ticket.html b/templates/moderation/ticket.html
index 4481a4ea2..179f1cc6b 100644
--- a/templates/moderation/ticket.html
+++ b/templates/moderation/ticket.html
@@ -57,10 +57,10 @@ Messages ({{ticket.messages.all.count}})
{% endif %}
{% endfor %}
{% if request.user.is_authenticated %}
-
{% else %}
Please
log in to add a message to this ticket
diff --git a/templates/molecules/form.html b/templates/molecules/form.html
new file mode 100644
index 000000000..e69de29bb
diff --git a/templates/sounds/modal_flag_sound.html b/templates/sounds/modal_flag_sound.html
index e8b19f441..5f8e230ad 100644
--- a/templates/sounds/modal_flag_sound.html
+++ b/templates/sounds/modal_flag_sound.html
@@ -11,9 +11,9 @@
Flag sound
-
diff --git a/templates/support/contact.html b/templates/support/contact.html
index 5a3132fa6..1d2fc7c5a 100644
--- a/templates/support/contact.html
+++ b/templates/support/contact.html
@@ -9,9 +9,9 @@
Thank you for contacting support, we will reply as soon as possible.
{% else %}
Use the form below to submit a support request. Please read the Frequently Asked Questions page before you send a support request.
-
{% endif %}
diff --git a/templates/wiki/edit.html b/templates/wiki/edit.html
index 13f31a36a..7fa9d1848 100644
--- a/templates/wiki/edit.html
+++ b/templates/wiki/edit.html
@@ -16,10 +16,10 @@
{% endif %}
{% endif %}
-
From 93375cd60461a10c63874288190dc462fec58f2b Mon Sep 17 00:00:00 2001
From: ffont
Date: Wed, 12 Feb 2025 10:42:50 +0100
Subject: [PATCH 3/5] Add extra test run task
---
freesound.code-workspace | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/freesound.code-workspace b/freesound.code-workspace
index 4dc94ba62..abd1d0e86 100644
--- a/freesound.code-workspace
+++ b/freesound.code-workspace
@@ -71,6 +71,12 @@
"command": "docker compose run --rm web python manage.py test --settings=freesound.test_settings",
"problemMatcher": []
},
+ {
+ "label": "Run tests with warnings",
+ "type": "shell",
+ "command": "docker compose run --rm web python -Wa manage.py test --settings=freesound.test_settings",
+ "problemMatcher": []
+ },
{
"label": "Run tests verbose with warnings",
"type": "shell",
From 81558435758be620bae9a11edd787ff377b1aaa8 Mon Sep 17 00:00:00 2001
From: ffont
Date: Wed, 12 Feb 2025 10:45:02 +0100
Subject: [PATCH 4/5] Fix some django warnings
---
accounts/models.py | 6 +++---
apiv2/tests.py | 4 ++--
geotags/views.py | 4 ++--
sounds/models.py | 4 ++--
4 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/accounts/models.py b/accounts/models.py
index addce2d5b..763b6f95e 100644
--- a/accounts/models.py
+++ b/accounts/models.py
@@ -37,9 +37,9 @@
from django.templatetags.static import static
from django.urls import reverse
from django.utils.encoding import smart_str
-from django.utils.http import urlquote
from django.utils.timezone import now
from psycopg2.errors import ForeignKeyViolation
+from urllib.parse import quote
import tickets.models
from apiv2.models import ApiV2Client
@@ -224,10 +224,10 @@ def get_absolute_url(self):
return reverse('account', args=[smart_str(self.user.username)])
def get_user_sounds_in_search_url(self):
- return f'{reverse("sounds-search")}?f=username:"{ urlquote(self.user.username) }"&s=Date+added+(newest+first)&g=0'
+ return f'{reverse("sounds-search")}?f=username:"{ quote(self.user.username) }"&s=Date+added+(newest+first)&g=0'
def get_user_packs_in_search_url(self):
- return f'{reverse("sounds-search")}?f=username:"{ urlquote(self.user.username) }"&s=Date+added+(newest+first)&g=1&dp=1'
+ return f'{reverse("sounds-search")}?f=username:"{ quote(self.user.username) }"&s=Date+added+(newest+first)&g=1&dp=1'
def get_latest_packs_for_profile_page(self):
latest_pack_ids = Pack.objects.select_related().filter(user=self.user, num_sounds__gt=0).exclude(is_deleted=True) \
diff --git a/apiv2/tests.py b/apiv2/tests.py
index e77144471..fa4b3deb9 100755
--- a/apiv2/tests.py
+++ b/apiv2/tests.py
@@ -636,7 +636,7 @@ def test_oauth2_authorization_code_grant_flow(self):
}, secure=True)
self.assertEqual(resp.status_code, 302)
resp = self.client.get(resp.request['PATH_INFO'] + '?' + resp.request['QUERY_STRING'], secure=True)
- self.assertEquals(resp.url.startswith(client.get_default_redirect_uri()), True)
+ self.assertEqual(resp.url.startswith(client.get_default_redirect_uri()), True)
resp_params = self.get_params_from_url(resp.url)
self.check_dict_has_fields(resp_params, ['error'])
self.assertEqual(resp_params['error'], 'unauthorized_client')
@@ -674,7 +674,7 @@ def test_oauth2_authorization_code_grant_flow(self):
}, secure=True)
self.assertTrue(resp.url.startswith(client.get_default_redirect_uri()))
resp_params = self.get_params_from_url(resp.url)
- self.assertEquals(resp_params['state'], 'an_optional_state') # Check state is returned and preserved
+ self.assertEqual(resp_params['state'], 'an_optional_state') # Check state is returned and preserved
self.check_dict_has_fields(resp_params, ['code']) # Check code is there
# Return 200 OK when requesting access token setting client_id and client_secret in body params
diff --git a/geotags/views.py b/geotags/views.py
index 2155b5294..f66481270 100644
--- a/geotags/views.py
+++ b/geotags/views.py
@@ -30,9 +30,9 @@
from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
-from django.utils.http import urlquote
from django.views.decorators.cache import cache_page
from django.views.decorators.clickjacking import xframe_options_exempt
+from urllib.parse import quote
from accounts.models import Profile
from sounds.models import Sound, Pack
@@ -211,7 +211,7 @@ def for_user(request, username):
'pack': None,
'sound': None,
'url': reverse('geotags-for-user-barray', args=[username]),
- 'query_search_page_url': reverse('sounds-search') + f'?f=username:{urlquote(username)}&mm=1'
+ 'query_search_page_url': reverse('sounds-search') + f'?f=username:{quote(username)}&mm=1'
})
return render(request, 'geotags/geotags.html', tvars)
diff --git a/sounds/models.py b/sounds/models.py
index 8284f1460..394ba749e 100644
--- a/sounds/models.py
+++ b/sounds/models.py
@@ -44,9 +44,9 @@
from django.template.loader import render_to_string
from django.urls import reverse
from django.utils.encoding import smart_str
-from django.utils.http import urlquote
from django.utils.functional import cached_property
from django.utils.text import Truncator, slugify
+from urllib.parse import quote
import accounts.models
from apiv2.models import ApiV2Client
@@ -1746,7 +1746,7 @@ def get_pack_tags(self):
return False
def pack_filter_value(self):
- return f"\"{self.id}_{urlquote(self.name)}\""
+ return f"\"{self.id}_{quote(self.name)}\""
def browse_pack_tag_url(self, tag):
return reverse('tags', args=[tag]) + f'?pack_flt={self.pack_filter_value()}'
From 368ce4b68a40007b407287de306d4d5cec3b5285 Mon Sep 17 00:00:00 2001
From: ffont
Date: Wed, 12 Feb 2025 13:39:10 +0100
Subject: [PATCH 5/5] Upgrade to Django 4.2
---
accounts/forms.py | 12 ++---
accounts/tests/test_user.py | 2 +-
freesound/middleware.py | 23 ---------
freesound/settings.py | 50 ++------------------
messages/forms.py | 2 +-
messages/tests/test_message_notifications.py | 4 +-
requirements.in | 31 ++++++------
requirements.txt | 49 ++++++++++---------
search/views.py | 2 +-
sounds/forms.py | 2 +-
sounds/views.py | 2 +-
support/forms.py | 2 +-
tickets/forms.py | 2 +-
13 files changed, 58 insertions(+), 125 deletions(-)
diff --git a/accounts/forms.py b/accounts/forms.py
index 38446cdd5..32a9ef3b9 100644
--- a/accounts/forms.py
+++ b/accounts/forms.py
@@ -20,7 +20,7 @@
import logging
-from captcha.fields import ReCaptchaField
+from django_recaptcha.fields import ReCaptchaField
from django import forms
from django.conf import settings
from django.contrib.auth import get_user_model
@@ -37,7 +37,7 @@
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from django.utils.safestring import mark_safe
-from multiupload.fields import MultiFileField
+from multiupload_plus.fields import MultiFileField
from accounts.models import Profile, EmailPreferenceType, OldUsername, DeletedUser
from utils.encryption import sign_with_timestamp, unsign_with_timestamp
@@ -101,8 +101,8 @@ class FlashUploadFileForm(forms.Form):
class TermsOfServiceForm(forms.Form):
accepted_tos = forms.BooleanField(
label='',
- help_text='Check this box to accept the terms of use '
- 'and the privacy policy of Freesound (required)',
+ help_text='Check this box to accept the terms of use '
+ 'and the privacy policy of Freesound (required)',
required=True,
error_messages={'required': 'You must accept the terms of use and the privacy poclicy in order to continue '
'using Freesound.'}
@@ -210,8 +210,8 @@ class RegistrationForm(forms.Form):
email2 = forms.EmailField(label=False, help_text=False, max_length=254)
password1 = forms.CharField(label=False, help_text=False, widget=forms.PasswordInput)
accepted_tos = forms.BooleanField(
- label=mark_safe('Check this box to accept our terms of '
- 'use and the privacy policy'),
+ label=mark_safe('Check this box to accept our terms of '
+ 'use and the privacy policy'),
required=True,
error_messages={'required': 'You must accept the terms of use in order to register to Freesound'}
)
diff --git a/accounts/tests/test_user.py b/accounts/tests/test_user.py
index 3be72b7f3..87e25bef1 100644
--- a/accounts/tests/test_user.py
+++ b/accounts/tests/test_user.py
@@ -52,7 +52,7 @@ def test_user_save(self):
self.assertEqual(Profile.objects.filter(user=u).exists(), True)
u.save() # Check saving user again (with existing profile) does not fail
- @mock.patch("captcha.fields.ReCaptchaField.validate")
+ @mock.patch("django_recaptcha.fields.ReCaptchaField.validate")
def test_user_registration(self, magic_mock_function):
username = 'new_user'
diff --git a/freesound/middleware.py b/freesound/middleware.py
index 3dda4db0e..092fc0cf2 100644
--- a/freesound/middleware.py
+++ b/freesound/middleware.py
@@ -20,7 +20,6 @@
import logging
-from admin_reorder.middleware import ModelAdminReorder
from django.conf import settings
from django.http import HttpResponseRedirect
from django.urls import reverse
@@ -125,25 +124,3 @@ def __call__(self, request):
response = self.get_response(request)
return response
-
-
-class ModelAdminReorderWithNav(ModelAdminReorder):
- # Customize ModelAdminReorder middleware so that it also reorders new django admin sidebar in 3.1+
- # from https://github.com/mishbahr/django-modeladmin-reorder/issues/47
-
- def process_template_response(self, request, response):
-
- if (
- getattr(response, 'context_data', None)
- and not response.context_data.get('app_list')
- and response.context_data.get('available_apps')
- ):
- available_apps = response.context_data.get('available_apps')
- response.context_data['app_list'] = available_apps
- response = super().process_template_response(request, response)
- response.context_data['available_apps'] = response.context_data[
- 'app_list'
- ]
- return response
-
- return super().process_template_response(request, response)
\ No newline at end of file
diff --git a/freesound/settings.py b/freesound/settings.py
index 8bcc8449c..cd0d485bf 100644
--- a/freesound/settings.py
+++ b/freesound/settings.py
@@ -31,8 +31,7 @@
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'silk.middleware.SilkyMiddleware',
- #'freesound.middleware.ModelAdminReorderWithNav',
- 'ratelimit.middleware.RatelimitMiddleware',
+ 'django_ratelimit.middleware.RatelimitMiddleware',
'freesound.middleware.TosAcceptanceHandler',
'freesound.middleware.BulkChangeLicenseHandler',
'freesound.middleware.UpdateEmailHandler',
@@ -75,51 +74,10 @@
'monitor',
'django_object_actions',
'silk',
- 'admin_reorder',
- 'captcha',
+ 'django_recaptcha',
'adminsortable',
]
-# Specify custom ordering of models in Django Admin index
-ADMIN_REORDER = (
-
- {'app': 'accounts', 'models': (
- 'auth.User',
- 'accounts.Profile',
- 'accounts.DeletedUser',
- 'accounts.UserDeletionRequest',
- 'accounts.UserFlag',
- 'accounts.OldUsername',
- 'accounts.EmailBounce',
- 'auth.Groups',
- 'fsmessages.Message',
- 'accounts.GdprAcceptance',
- )},
- {'app': 'sounds', 'models': (
- 'sounds.Sound',
- {'model': 'sounds.SoundAnalysis', 'label': 'Sound analyses'},
- 'sounds.Pack',
- 'sounds.DeletedSound',
- 'sounds.License',
- {'model': 'sounds.Flag', 'label': 'Sound flags'},
- 'sounds.BulkUploadProgress',
- {'model': 'sounds.SoundOfTheDay', 'label': 'Sound of the day'}
- )},
- {'app': 'apiv2', 'label': 'API', 'models': (
- {'model': 'apiv2.ApiV2Client', 'label': 'API V2 Application'},
- 'oauth2_provider.AccessToken',
- 'oauth2_provider.RefreshToken',
- 'oauth2_provider.Grant',
- )},
- 'forum',
- {'app': 'donations', 'models': (
- 'donations.Donation',
- 'donations.DonationsEmailSettings',
- 'donations.DonationsModalSettings',
- )},
- 'sites',
-)
-
# Silk is the Request/SQL logging platform. We install it but leave it disabled
# It can be activated in local_settings by changing INTERCEPT_FUNC
SILKY_AUTHENTICATION = True # User must login
@@ -127,7 +85,7 @@
SILKY_PERMISSIONS = lambda user: user.is_superuser
SILKY_INTERCEPT_FUNC = lambda request: False
-CORS_ORIGIN_ALLOW_ALL = True
+CORS_ALLOW_ALL_ORIGINS = True
AUTHENTICATION_BACKENDS = ('accounts.modelbackend.CustomModelBackend',)
@@ -715,7 +673,7 @@
# To bypass the security check that prevents the test keys from being used unknowingly add
# SILENCED_SYSTEM_CHECKS = [..., 'captcha.recaptcha_test_key_error', ...] to your settings.
-SILENCED_SYSTEM_CHECKS += ['captcha.recaptcha_test_key_error']
+SILENCED_SYSTEM_CHECKS += ['django_recaptcha.recaptcha_test_key_error']
# -------------------------------------------------------------------------------
diff --git a/messages/forms.py b/messages/forms.py
index 6241cff4a..1177cec59 100644
--- a/messages/forms.py
+++ b/messages/forms.py
@@ -18,7 +18,7 @@
# See AUTHORS file.
#
-from captcha.fields import ReCaptchaField
+from django_recaptcha.fields import ReCaptchaField
from django import forms
from django.contrib.auth.models import User
from django.urls import reverse
diff --git a/messages/tests/test_message_notifications.py b/messages/tests/test_message_notifications.py
index bdc8baeb9..ba3cb2494 100644
--- a/messages/tests/test_message_notifications.py
+++ b/messages/tests/test_message_notifications.py
@@ -39,7 +39,7 @@ def setUp(self):
self.sender = User.objects.create_user(username='sender', email='sender@example.com')
self.receiver = User.objects.create_user(username='receiver', email='receiver@example.com')
- @mock.patch("captcha.fields.ReCaptchaField.validate")
+ @mock.patch("django_recaptcha.fields.ReCaptchaField.validate")
def test_message_email_preference_enabled(self, magic_mock):
self.client.force_login(user=self.sender)
resp = self.client.post(reverse('messages-new'), data={
@@ -52,7 +52,7 @@ def test_message_email_preference_enabled(self, magic_mock):
self.assertTrue(settings.EMAIL_SUBJECT_PREFIX in mail.outbox[0].subject)
self.assertTrue(settings.EMAIL_SUBJECT_PRIVATE_MESSAGE in mail.outbox[0].subject)
- @mock.patch("captcha.fields.ReCaptchaField.validate")
+ @mock.patch("django_recaptcha.fields.ReCaptchaField.validate")
def test_message_email_preference_disabled(self, magic_mock):
# Create email preference object for the email type (which will mean user does not want message emails as
# it is enabled by default and the preference indicates user does not want it).
diff --git a/requirements.in b/requirements.in
index 96b291a67..6b0d29dee 100644
--- a/requirements.in
+++ b/requirements.in
@@ -5,25 +5,24 @@ bleach==5.0.1
boto3==1.26.130
celery==5.3.4
debugpy==1.5.1
-dj-database-url==0.5.0
-django-admin-sortable==2.2.4
+dj-database-url==2.3.0
+django-admin-sortable==2.3
django-amazon-ses==4.0.1
-django-cors-headers==3.13.0
-django-debug-toolbar==3.1.1
-django-extensions==3.1.5
-django-modeladmin-reorder==0.3.1
-django-multiupload==0.6.1
-django-oauth-toolkit==2.2.0
-django-object-actions==4.1.0
-django-ratelimit==3.0.1
-django-recaptcha==3.0.0
-django-redis==5.2.0
-django-silk==5.0.3
-Django~=3.2.23
+django-cors-headers==4.7.0
+django-debug-toolbar==5.0.1
+django-extensions==3.2.3
+django-multiupload-plus==0.1.0
+django-oauth-toolkit==3.0.1
+django-object-actions==4.3.0
+django-ratelimit==4.1.0
+django-recaptcha==4.0.0
+django-redis==5.4.0
+django-silk==5.3.2
+Django~=4.2.19
djangorestframework-jsonp==1.0.2
djangorestframework-xml==2.0.0
djangorestframework-yaml==2.0.0
-djangorestframework==3.13.1
+djangorestframework==3.15.2
fabric==2.6.0
feedparser~=6.0.10
freezegun==1.2.2
@@ -52,7 +51,7 @@ PyYAML==6.0.1
redis==3.2.0
scikit-learn==1.4.1.post1 # clustering
scipy==1.12.0 # clustering
-sentry-sdk[django]~=1.31
+sentry-sdk[django]~=2.21.0
Sphinx==1.6.3
stripe==2.28.1
xlrd==2.0.1 # for reading .xls files (but not .xlsx)
diff --git a/requirements.txt b/requirements.txt
index c0072a874..635f0edbc 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,7 +11,9 @@ alabaster==0.7.13
amqp==5.2.0
# via kombu
asgiref==3.7.2
- # via django
+ # via
+ # django
+ # django-cors-headers
asttokens==2.4.1
# via stack-data
autopep8==1.5.7
@@ -82,51 +84,49 @@ defusedxml==0.7.1
# via djangorestframework-xml
deprecated==1.2.14
# via jwcrypto
-dj-database-url==0.5.0
+dj-database-url==2.3.0
# via -r requirements.in
-django==3.2.23
+django==4.2.19
# via
# -r requirements.in
+ # dj-database-url
# django-admin-sortable
# django-amazon-ses
# django-cors-headers
# django-debug-toolbar
# django-extensions
- # django-modeladmin-reorder
- # django-multiupload
+ # django-multiupload-plus
# django-oauth-toolkit
# django-recaptcha
# django-redis
# django-silk
# djangorestframework
# sentry-sdk
-django-admin-sortable==2.2.4
+django-admin-sortable==2.3
# via -r requirements.in
django-amazon-ses==4.0.1
# via -r requirements.in
-django-cors-headers==3.13.0
+django-cors-headers==4.7.0
# via -r requirements.in
-django-debug-toolbar==3.1.1
+django-debug-toolbar==5.0.1
# via -r requirements.in
-django-extensions==3.1.5
+django-extensions==3.2.3
# via -r requirements.in
-django-modeladmin-reorder==0.3.1
+django-multiupload-plus==0.1.0
# via -r requirements.in
-django-multiupload==0.6.1
+django-oauth-toolkit==3.0.1
# via -r requirements.in
-django-oauth-toolkit==2.2.0
+django-object-actions==4.3.0
# via -r requirements.in
-django-object-actions==4.1.0
+django-ratelimit==4.1.0
# via -r requirements.in
-django-ratelimit==3.0.1
+django-recaptcha==4.0.0
# via -r requirements.in
-django-recaptcha==3.0.0
+django-redis==5.4.0
# via -r requirements.in
-django-redis==5.2.0
+django-silk==5.3.2
# via -r requirements.in
-django-silk==5.0.3
- # via -r requirements.in
-djangorestframework==3.13.1
+djangorestframework==3.15.2
# via -r requirements.in
djangorestframework-jsonp==1.0.2
# via -r requirements.in
@@ -271,10 +271,7 @@ python-dateutil==2.8.2
python-louvain==0.16
# via -r requirements.in
pytz==2023.3
- # via
- # -r requirements.in
- # django
- # djangorestframework
+ # via -r requirements.in
pyyaml==6.0.1
# via
# -r requirements.in
@@ -301,7 +298,7 @@ scipy==1.12.0
# via
# -r requirements.in
# scikit-learn
-sentry-sdk[django]==1.39.1
+sentry-sdk[django]==2.21.0
# via -r requirements.in
sgmllib3k==1.0.0
# via feedparser
@@ -345,7 +342,9 @@ traitlets==5.14.0
# ipython
# matplotlib-inline
typing-extensions==4.9.0
- # via asgiref
+ # via
+ # asgiref
+ # dj-database-url
tzdata==2023.4
# via celery
uritemplate==4.1.1
diff --git a/search/views.py b/search/views.py
index 7cbcccd73..2b2900969 100644
--- a/search/views.py
+++ b/search/views.py
@@ -27,7 +27,7 @@
from django.conf import settings
from django.http import JsonResponse
from django.shortcuts import get_object_or_404, reverse, render
-from ratelimit.decorators import ratelimit
+from django_ratelimit.decorators import ratelimit
import forum
import sounds
diff --git a/sounds/forms.py b/sounds/forms.py
index 59e1b846e..d1c95fc91 100644
--- a/sounds/forms.py
+++ b/sounds/forms.py
@@ -21,7 +21,7 @@
import re
-from captcha.fields import ReCaptchaField
+from django_recaptcha.fields import ReCaptchaField
from django import forms
from django.core.exceptions import PermissionDenied
from django.db.models import Q
diff --git a/sounds/views.py b/sounds/views.py
index cf5125486..2ba215409 100644
--- a/sounds/views.py
+++ b/sounds/views.py
@@ -45,7 +45,7 @@
from django.template import loader
from django.urls import reverse, resolve
from django.views.decorators.clickjacking import xframe_options_exempt
-from ratelimit.decorators import ratelimit
+from django_ratelimit.decorators import ratelimit
from accounts.models import Profile
from comments.forms import CommentForm
diff --git a/support/forms.py b/support/forms.py
index 8934ea364..8a9b3c615 100644
--- a/support/forms.py
+++ b/support/forms.py
@@ -18,7 +18,7 @@
# See AUTHORS file.
#
-from captcha.fields import ReCaptchaField
+from django_recaptcha.fields import ReCaptchaField
from django import forms
diff --git a/tickets/forms.py b/tickets/forms.py
index 5c263e0d9..09e7ea2ae 100644
--- a/tickets/forms.py
+++ b/tickets/forms.py
@@ -18,7 +18,7 @@
# See AUTHORS file.
#
-from captcha.fields import ReCaptchaField
+from django_recaptcha.fields import ReCaptchaField
from django import forms
from django.utils.safestring import mark_safe