Chore(deps): Bump the django group across 1 directory with 9 updates (#10538)

* Chore(deps): Bump the django group across 1 directory with 9 updates

Bumps the django group with 9 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [django](https://github.com/django/django) | `5.1.8` | `5.2.5` |
| [django-auditlog](https://github.com/jazzband/django-auditlog) | `3.1.2` | `3.2.1` |
| [django-guardian](https://github.com/django-guardian/django-guardian) | `2.4.0` | `3.0.3` |
| [django-multiselectfield](https://github.com/goinnn/django-multiselectfield) | `0.1.13` | `1.0.1` |
| [django-soft-delete](https://github.com/san4ezy/django_softdelete) | `1.0.18` | `1.0.19` |
| [djangorestframework](https://github.com/encode/django-rest-framework) | `3.16.0` | `3.16.1` |
| [djangorestframework-guardian](https://github.com/rpkilby/django-rest-framework-guardian) | `0.3.0` | `0.4.0` |
| [drf-spectacular-sidecar](https://github.com/tfranzel/drf-spectacular-sidecar) | `2025.4.1` | `2025.8.1` |
| [pytest-django](https://github.com/pytest-dev/pytest-django) | `4.10.0` | `4.11.1` |



Updates `django` from 5.1.8 to 5.2.5
- [Commits](https://github.com/django/django/compare/5.1.8...5.2.5)

Updates `django-auditlog` from 3.1.2 to 3.2.1
- [Release notes](https://github.com/jazzband/django-auditlog/releases)
- [Changelog](https://github.com/jazzband/django-auditlog/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jazzband/django-auditlog/compare/v3.1.2...v3.2.1)

Updates `django-guardian` from 2.4.0 to 3.0.3
- [Release notes](https://github.com/django-guardian/django-guardian/releases)
- [Commits](https://github.com/django-guardian/django-guardian/compare/v2.4.0...3.0.3)

Updates `django-multiselectfield` from 0.1.13 to 1.0.1
- [Release notes](https://github.com/goinnn/django-multiselectfield/releases)
- [Changelog](https://github.com/goinnn/django-multiselectfield/blob/master/CHANGES.rst)
- [Commits](https://github.com/goinnn/django-multiselectfield/compare/v0.1.13...v1.0.1)

Updates `django-soft-delete` from 1.0.18 to 1.0.19
- [Changelog](https://github.com/san4ezy/django_softdelete/blob/master/CHANGELOG.md)
- [Commits](https://github.com/san4ezy/django_softdelete/commits)

Updates `djangorestframework` from 3.16.0 to 3.16.1
- [Release notes](https://github.com/encode/django-rest-framework/releases)
- [Commits](https://github.com/encode/django-rest-framework/compare/3.16.0...3.16.1)

Updates `djangorestframework-guardian` from 0.3.0 to 0.4.0
- [Changelog](https://github.com/rpkilby/django-rest-framework-guardian/blob/master/CHANGELOG)
- [Commits](https://github.com/rpkilby/django-rest-framework-guardian/compare/0.3.0...0.4.0)

Updates `drf-spectacular-sidecar` from 2025.4.1 to 2025.8.1
- [Commits](https://github.com/tfranzel/drf-spectacular-sidecar/compare/2025.4.1...2025.8.1)

Updates `pytest-django` from 4.10.0 to 4.11.1
- [Release notes](https://github.com/pytest-dev/pytest-django/releases)
- [Changelog](https://github.com/pytest-dev/pytest-django/blob/main/docs/changelog.rst)
- [Commits](https://github.com/pytest-dev/pytest-django/compare/v4.10.0...v4.11.1)

---
updated-dependencies:
- dependency-name: django
  dependency-version: 5.2.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: django
- dependency-name: django-auditlog
  dependency-version: 3.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: django
- dependency-name: django-guardian
  dependency-version: 3.0.3
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: django
- dependency-name: django-multiselectfield
  dependency-version: 1.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: django
- dependency-name: django-soft-delete
  dependency-version: 1.0.19
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: django
- dependency-name: djangorestframework
  dependency-version: 3.16.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: django
- dependency-name: djangorestframework-guardian
  dependency-version: 0.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: django
- dependency-name: drf-spectacular-sidecar
  dependency-version: 2025.8.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: django
- dependency-name: pytest-django
  dependency-version: 4.11.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: django
...

Signed-off-by: dependabot[bot] <support@github.com>

* Fix log matches related to newlines, add newlines to stdout.writelines

* Fix disable api remote auth test, Django 5.2 no longer uses process_request

* Remove postgres version check

* Update administration.md

* Handle django-multiselectfield v1.0 changes

* Update administration.md

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
This commit is contained in:
dependabot[bot]
2025-08-11 13:45:14 -07:00
committed by GitHub
parent 1b6ec65f6e
commit edb8c06e2a
12 changed files with 85 additions and 127 deletions

View File

@@ -179,10 +179,14 @@ following:
### Database Upgrades ### Database Upgrades
In general, paperless does not require a specific version of PostgreSQL or MariaDB and it is Paperless-ngx is compatible with Django-supported versions of PostgreSQL and MariaDB and it is generally
safe to update them to newer versions. However, you should always take a backup and follow safe to update them to newer versions. However, you should always take a backup and follow
the instructions from your database's documentation for how to upgrade between major versions. the instructions from your database's documentation for how to upgrade between major versions.
!!! note
As of Paperless-ngx v2.18, the minimum supported version of PostgreSQL is 13.
For PostgreSQL, refer to [Upgrading a PostgreSQL Cluster](https://www.postgresql.org/docs/current/upgrading.html). For PostgreSQL, refer to [Upgrading a PostgreSQL Cluster](https://www.postgresql.org/docs/current/upgrading.html).
For MariaDB, refer to [Upgrading MariaDB](https://mariadb.com/kb/en/upgrading/) For MariaDB, refer to [Upgrading MariaDB](https://mariadb.com/kb/en/upgrading/)

View File

@@ -23,22 +23,22 @@ dependencies = [
"dateparser~=1.2", "dateparser~=1.2",
# WARNING: django does not use semver. # WARNING: django does not use semver.
# Only patch versions are guaranteed to not introduce breaking changes. # Only patch versions are guaranteed to not introduce breaking changes.
"django~=5.1.7", "django~=5.2.5",
"django-allauth[socialaccount,mfa]~=65.4.0", "django-allauth[socialaccount,mfa]~=65.4.0",
"django-auditlog~=3.1.2", "django-auditlog~=3.2.1",
"django-cachalot~=2.8.0", "django-cachalot~=2.8.0",
"django-celery-results~=2.6.0", "django-celery-results~=2.6.0",
"django-compression-middleware~=0.5.0", "django-compression-middleware~=0.5.0",
"django-cors-headers~=4.7.0", "django-cors-headers~=4.7.0",
"django-extensions~=4.1", "django-extensions~=4.1",
"django-filter~=25.1", "django-filter~=25.1",
"django-guardian~=2.4.0", "django-guardian~=3.0.3",
"django-multiselectfield~=0.1.13", "django-multiselectfield~=1.0.1",
"django-soft-delete~=1.0.18", "django-soft-delete~=1.0.18",
"djangorestframework~=3.15", "djangorestframework~=3.15",
"djangorestframework-guardian~=0.3.0", "djangorestframework-guardian~=0.4.0",
"drf-spectacular~=0.28", "drf-spectacular~=0.28",
"drf-spectacular-sidecar~=2025.4.1", "drf-spectacular-sidecar~=2025.8.1",
"drf-writable-nested~=0.7.1", "drf-writable-nested~=0.7.1",
"filelock~=3.18.0", "filelock~=3.18.0",
"flower~=2.0.1", "flower~=2.0.1",
@@ -103,7 +103,7 @@ testing = [
"imagehash", "imagehash",
"pytest~=8.4.1", "pytest~=8.4.1",
"pytest-cov~=6.2.1", "pytest-cov~=6.2.1",
"pytest-django~=4.10.0", "pytest-django~=4.11.1",
"pytest-env", "pytest-env",
"pytest-httpx", "pytest-httpx",
"pytest-mock", "pytest-mock",

View File

@@ -125,14 +125,14 @@ class Command(MultiProcessMixin, ProgressBarMixin, BaseCommand):
messages.append( messages.append(
self.style.NOTICE( self.style.NOTICE(
f"Document {result.doc_one_pk} fuzzy match" f"Document {result.doc_one_pk} fuzzy match"
f" to {result.doc_two_pk} (confidence {result.ratio:.3f})", f" to {result.doc_two_pk} (confidence {result.ratio:.3f})\n",
), ),
) )
maybe_delete_ids.append(result.doc_two_pk) maybe_delete_ids.append(result.doc_two_pk)
if len(messages) == 0: if len(messages) == 0:
messages.append( messages.append(
self.style.SUCCESS("No matches found"), self.style.SUCCESS("No matches found\n"),
) )
self.stdout.writelines( self.stdout.writelines(
messages, messages,

View File

@@ -2089,6 +2089,24 @@ class WorkflowTriggerSerializer(serializers.ModelSerializer):
return attrs return attrs
@staticmethod
def normalize_workflow_trigger_sources(trigger):
"""
Convert sources to strings to handle django-multiselectfield v1.0 changes
"""
if trigger and "sources" in trigger:
trigger["sources"] = [
str(s.value if hasattr(s, "value") else s) for s in trigger["sources"]
]
def create(self, validated_data):
WorkflowTriggerSerializer.normalize_workflow_trigger_sources(validated_data)
return super().create(validated_data)
def update(self, instance, validated_data):
WorkflowTriggerSerializer.normalize_workflow_trigger_sources(validated_data)
return super().update(instance, validated_data)
class WorkflowActionEmailSerializer(serializers.ModelSerializer): class WorkflowActionEmailSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(allow_null=True, required=False) id = serializers.IntegerField(allow_null=True, required=False)
@@ -2253,6 +2271,8 @@ class WorkflowSerializer(serializers.ModelSerializer):
if triggers is not None and triggers is not serializers.empty: if triggers is not None and triggers is not serializers.empty:
for trigger in triggers: for trigger in triggers:
filter_has_tags = trigger.pop("filter_has_tags", None) filter_has_tags = trigger.pop("filter_has_tags", None)
# Convert sources to strings to handle django-multiselectfield v1.0 changes
WorkflowTriggerSerializer.normalize_workflow_trigger_sources(trigger)
trigger_instance, _ = WorkflowTrigger.objects.update_or_create( trigger_instance, _ = WorkflowTrigger.objects.update_or_create(
id=trigger.get("id"), id=trigger.get("id"),
defaults=trigger, defaults=trigger,

View File

@@ -123,7 +123,7 @@ class TestExportImport(
self.trigger = WorkflowTrigger.objects.create( self.trigger = WorkflowTrigger.objects.create(
type=WorkflowTrigger.WorkflowTriggerType.CONSUMPTION, type=WorkflowTrigger.WorkflowTriggerType.CONSUMPTION,
sources=[1], sources=[str(WorkflowTrigger.DocumentSourceChoices.CONSUME_FOLDER.value)],
filter_filename="*", filter_filename="*",
) )
self.action = WorkflowAction.objects.create(assign_title="new title") self.action = WorkflowAction.objects.create(assign_title="new title")

View File

@@ -87,7 +87,7 @@ class TestFuzzyMatchCommand(TestCase):
filename="other_test.pdf", filename="other_test.pdf",
) )
stdout, _ = self.call_command() stdout, _ = self.call_command()
self.assertEqual(stdout, "No matches found\n") self.assertIn("No matches found", stdout)
def test_with_matches(self): def test_with_matches(self):
""" """
@@ -116,7 +116,7 @@ class TestFuzzyMatchCommand(TestCase):
filename="other_test.pdf", filename="other_test.pdf",
) )
stdout, _ = self.call_command("--processes", "1") stdout, _ = self.call_command("--processes", "1")
self.assertRegex(stdout, self.MSG_REGEX + "\n") self.assertRegex(stdout, self.MSG_REGEX)
def test_with_3_matches(self): def test_with_3_matches(self):
""" """
@@ -152,11 +152,10 @@ class TestFuzzyMatchCommand(TestCase):
filename="final_test.pdf", filename="final_test.pdf",
) )
stdout, _ = self.call_command() stdout, _ = self.call_command()
lines = [x.strip() for x in stdout.split("\n") if len(x.strip())] lines = [x.strip() for x in stdout.splitlines() if x.strip()]
self.assertEqual(len(lines), 3) self.assertEqual(len(lines), 3)
self.assertRegex(lines[0], self.MSG_REGEX) for line in lines:
self.assertRegex(lines[1], self.MSG_REGEX) self.assertRegex(line, self.MSG_REGEX)
self.assertRegex(lines[2], self.MSG_REGEX)
def test_document_deletion(self): def test_document_deletion(self):
""" """
@@ -197,14 +196,12 @@ class TestFuzzyMatchCommand(TestCase):
stdout, _ = self.call_command("--delete") stdout, _ = self.call_command("--delete")
lines = [x.strip() for x in stdout.split("\n") if len(x.strip())] self.assertIn(
self.assertEqual(len(lines), 3)
self.assertEqual(
lines[0],
"The command is configured to delete documents. Use with caution", "The command is configured to delete documents. Use with caution",
stdout,
) )
self.assertRegex(lines[1], self.MSG_REGEX) self.assertRegex(stdout, self.MSG_REGEX)
self.assertEqual(lines[2], "Deleting 1 documents based on ratio matches") self.assertIn("Deleting 1 documents based on ratio matches", stdout)
self.assertEqual(Document.objects.count(), 2) self.assertEqual(Document.objects.count(), 2)
self.assertIsNotNone(Document.objects.get(pk=1)) self.assertIsNotNone(Document.objects.get(pk=1))

View File

@@ -104,7 +104,7 @@ class TestReverseMigrateWorkflow(TestMigrations):
trigger = WorkflowTrigger.objects.create( trigger = WorkflowTrigger.objects.create(
type=0, type=0,
sources=[DocumentSource.ConsumeFolder], sources=[str(DocumentSource.ConsumeFolder)],
filter_path="*/path/*", filter_path="*/path/*",
filter_filename="*file*", filter_filename="*file*",
) )

View File

@@ -54,7 +54,7 @@ class HttpRemoteUserMiddleware(PersistentRemoteUserMiddleware):
header = settings.HTTP_REMOTE_USER_HEADER_NAME header = settings.HTTP_REMOTE_USER_HEADER_NAME
def process_request(self, request: HttpRequest) -> None: def __call__(self, request: HttpRequest) -> None:
# If remote user auth is enabled only for the frontend, not the API, # If remote user auth is enabled only for the frontend, not the API,
# then we need dont want to authenticate the user for API requests. # then we need dont want to authenticate the user for API requests.
if ( if (
@@ -62,8 +62,8 @@ class HttpRemoteUserMiddleware(PersistentRemoteUserMiddleware):
and "paperless.auth.PaperlessRemoteUserAuthentication" and "paperless.auth.PaperlessRemoteUserAuthentication"
not in settings.REST_FRAMEWORK["DEFAULT_AUTHENTICATION_CLASSES"] not in settings.REST_FRAMEWORK["DEFAULT_AUTHENTICATION_CLASSES"]
): ):
return return self.get_response(request)
return super().process_request(request) return super().__call__(request)
class PaperlessRemoteUserAuthentication(authentication.RemoteUserAuthentication): class PaperlessRemoteUserAuthentication(authentication.RemoteUserAuthentication):

View File

@@ -214,31 +214,3 @@ def audit_log_check(app_configs, **kwargs):
) )
return result return result
@register()
def check_postgres_version(app_configs, **kwargs):
"""
Django 5.2 removed PostgreSQL 13 support and thus it will be removed in
a future Paperless-ngx version. This check can be removed eventually.
See https://docs.djangoproject.com/en/5.2/releases/5.2/#dropped-support-for-postgresql-13
"""
db_conn = connections["default"]
result = []
if db_conn.vendor == "postgresql":
try:
with db_conn.cursor() as cursor:
cursor.execute("SHOW server_version;")
version = cursor.fetchone()[0]
if version.startswith("13"):
return [
Warning(
"PostgreSQL 13 is deprecated and will not be supported in a future Paperless-ngx release.",
hint="Upgrade to PostgreSQL 14 or newer.",
),
]
except Exception: # pragma: no cover
# Don't block checks on version query failure
pass
return result

View File

@@ -9,7 +9,6 @@ from documents.tests.utils import DirectoriesMixin
from documents.tests.utils import FileSystemAssertsMixin from documents.tests.utils import FileSystemAssertsMixin
from paperless.checks import audit_log_check from paperless.checks import audit_log_check
from paperless.checks import binaries_check from paperless.checks import binaries_check
from paperless.checks import check_postgres_version
from paperless.checks import debug_mode_check from paperless.checks import debug_mode_check
from paperless.checks import paths_check from paperless.checks import paths_check
from paperless.checks import settings_values_check from paperless.checks import settings_values_check
@@ -263,39 +262,3 @@ class TestAuditLogChecks(TestCase):
("auditlog table was found but audit log is disabled."), ("auditlog table was found but audit log is disabled."),
msg.msg, msg.msg,
) )
class TestPostgresVersionCheck(TestCase):
@mock.patch("paperless.checks.connections")
def test_postgres_13_warns(self, mock_connections):
mock_connection = mock.MagicMock()
mock_connection.vendor = "postgresql"
mock_cursor = mock.MagicMock()
mock_cursor.__enter__.return_value.fetchone.return_value = ["13.11"]
mock_connection.cursor.return_value = mock_cursor
mock_connections.__getitem__.return_value = mock_connection
warnings = check_postgres_version(None)
self.assertEqual(len(warnings), 1)
self.assertIn("PostgreSQL 13 is deprecated", warnings[0].msg)
@mock.patch("paperless.checks.connections")
def test_postgres_14_passes(self, mock_connections):
mock_connection = mock.MagicMock()
mock_connection.vendor = "postgresql"
mock_cursor = mock.MagicMock()
mock_cursor.__enter__.return_value.fetchone.return_value = ["14.10"]
mock_connection.cursor.return_value = mock_cursor
mock_connections.__getitem__.return_value = mock_connection
warnings = check_postgres_version(None)
self.assertEqual(warnings, [])
@mock.patch("paperless.checks.connections")
def test_non_postgres_skipped(self, mock_connections):
mock_connection = mock.MagicMock()
mock_connection.vendor = "sqlite"
mock_connections.__getitem__.return_value = mock_connection
warnings = check_postgres_version(None)
self.assertEqual(warnings, [])

View File

@@ -1,6 +1,7 @@
import os import os
from unittest import mock from unittest import mock
from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.test import override_settings from django.test import override_settings
from rest_framework import status from rest_framework import status
@@ -91,6 +92,7 @@ class TestRemoteUser(DirectoriesMixin, APITestCase):
@override_settings( @override_settings(
REST_FRAMEWORK={ REST_FRAMEWORK={
**settings.REST_FRAMEWORK,
"DEFAULT_AUTHENTICATION_CLASSES": [ "DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework.authentication.BasicAuthentication", "rest_framework.authentication.BasicAuthentication",
"rest_framework.authentication.TokenAuthentication", "rest_framework.authentication.TokenAuthentication",

70
uv.lock generated
View File

@@ -626,15 +626,15 @@ wheels = [
[[package]] [[package]]
name = "django" name = "django"
version = "5.1.8" version = "5.2.5"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "asgiref", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "asgiref", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
{ name = "sqlparse", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "sqlparse", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/00/40/45adc1b93435d1b418654a734b68351bb6ce0a0e5e37b2f0e9aeb1a2e233/Django-5.1.8.tar.gz", hash = "sha256:42e92a1dd2810072bcc40a39a212b693f94406d0ba0749e68eb642f31dc770b4", size = 10723602, upload-time = "2025-04-02T11:19:56.028Z" } sdist = { url = "https://files.pythonhosted.org/packages/62/9b/779f853c3d2d58b9e08346061ff3e331cdec3fe3f53aae509e256412a593/django-5.2.5.tar.gz", hash = "sha256:0745b25681b129a77aae3d4f6549b62d3913d74407831abaa0d9021a03954bae", size = 10859748, upload-time = "2025-08-06T08:26:29.978Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/ec/0d/e6dd0ed898b920fec35c6eeeb9acbeb831fff19ad21c5e684744df1d4a36/Django-5.1.8-py3-none-any.whl", hash = "sha256:11b28fa4b00e59d0def004e9ee012fefbb1065a5beb39ee838983fd24493ad4f", size = 8277130, upload-time = "2025-04-02T11:19:51.591Z" }, { url = "https://files.pythonhosted.org/packages/9d/6e/98a1d23648e0085bb5825326af17612ecd8fc76be0ce96ea4dc35e17b926/django-5.2.5-py3-none-any.whl", hash = "sha256:2b2ada0ee8a5ff743a40e2b9820d1f8e24c11bac9ae6469cd548f0057ea6ddcd", size = 8302999, upload-time = "2025-08-06T08:26:23.562Z" },
] ]
[[package]] [[package]]
@@ -660,15 +660,15 @@ socialaccount = [
[[package]] [[package]]
name = "django-auditlog" name = "django-auditlog"
version = "3.1.2" version = "3.2.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
{ name = "python-dateutil", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "python-dateutil", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/0e/3a/61bfb180019d08db3f7a2e4097bda14ee32bd57f5dffda0c84b2d4c26304/django_auditlog-3.1.2.tar.gz", hash = "sha256:435345b4055d16abfb4ada4bf11320f9e2f6d343874464471fa0041f13f3a474", size = 69359, upload-time = "2025-04-26T11:01:56.553Z" } sdist = { url = "https://files.pythonhosted.org/packages/e1/46/9da1d94493832fa18d2f6324a76d387fa232001593866987a96047709f4e/django_auditlog-3.2.1.tar.gz", hash = "sha256:63a4c9f7793e94eed804bc31a04d9b0b58244b1d280e2ed273c8b406bff1f779", size = 72926, upload-time = "2025-07-03T20:08:17.734Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/af/34/47edd758abcb4426953b5ff2fa4dd9956c2304e96160ab1b95c3a1ab6e61/django_auditlog-3.1.2-py3-none-any.whl", hash = "sha256:6432a83fdf4397a726488d101fedcb62daafd6d4b825a0fc4c50e3657f5883cd", size = 37312, upload-time = "2025-04-26T11:01:16.776Z" }, { url = "https://files.pythonhosted.org/packages/a7/06/67296d050a72dcd76f57f220df621cb27e5b9282ba7ad0f5f74870dce241/django_auditlog-3.2.1-py3-none-any.whl", hash = "sha256:99603ca9d015f7e9b062b1c34f3e0826a3ce6ae6e5950c81bb7e663f7802a899", size = 38330, upload-time = "2025-07-03T20:07:51.735Z" },
] ]
[[package]] [[package]]
@@ -764,38 +764,38 @@ wheels = [
[[package]] [[package]]
name = "django-guardian" name = "django-guardian"
version = "2.4.0" version = "3.0.3"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/6f/4c/d1f6923a0ad7f16c403a54c09e94acb76ac6c3765e02523fb09b2b03e1a8/django-guardian-2.4.0.tar.gz", hash = "sha256:c58a68ae76922d33e6bdc0e69af1892097838de56e93e78a8361090bcd9f89a0", size = 159008, upload-time = "2021-05-23T22:11:26.23Z" } sdist = { url = "https://files.pythonhosted.org/packages/30/c2/3ed43813dd7313f729dbaa829b4f9ed4a647530151f672cfb5f843c12edf/django_guardian-3.0.3.tar.gz", hash = "sha256:4e59eab4d836da5a027cf0c176d14bc2a4e22cbbdf753159a03946c08c8a196d", size = 85410, upload-time = "2025-06-25T20:42:17.475Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/a2/25/869df12e544b51f583254aadbba6c1a95e11d2d08edeb9e58dd715112db5/django_guardian-2.4.0-py3-none-any.whl", hash = "sha256:440ca61358427e575323648b25f8384739e54c38b3d655c81d75e0cd0d61b697", size = 106107, upload-time = "2021-05-23T22:11:22.75Z" }, { url = "https://files.pythonhosted.org/packages/8b/13/e6f629a978ef5fab8b8d2760cacc3e451016cef952cf4c049d672c5c6b07/django_guardian-3.0.3-py3-none-any.whl", hash = "sha256:d2164cea9f03c369d7ade21802710f3ab23ca6734bcc7dfcfb385906783916c7", size = 118198, upload-time = "2025-06-25T20:42:15.377Z" },
] ]
[[package]] [[package]]
name = "django-multiselectfield" name = "django-multiselectfield"
version = "0.1.13" version = "1.0.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/dd/c3/1a326cc669fea63f22e63f6e2b2b014534a15966506e8d7fa3c232aced42/django_multiselectfield-0.1.13.tar.gz", hash = "sha256:437d72632f4c0ca416951917632529c3d1d42b62bb6c3c03e3396fa50265be94", size = 11704, upload-time = "2024-07-01T05:40:39.456Z" } sdist = { url = "https://files.pythonhosted.org/packages/04/9a/27060e8aa491ff2d286054df2e89df481a8dfe0e5e459fa36c0f48e3c10c/django_multiselectfield-1.0.1.tar.gz", hash = "sha256:3f8b4fff3e07d4a91c8bb4b809bc35caeb22b41769b606f4c9edc53b8d72a667", size = 22025, upload-time = "2025-06-12T14:41:21.599Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/be/9e/3ed6f072f1e806516dbc8c95e4ecae7b87af6757eb5d428857ea0a097e76/django_multiselectfield-0.1.13-py3-none-any.whl", hash = "sha256:f146ef568c823a409f4021b98781666ec2debabfceca9176116d749dc39cb8b3", size = 14804, upload-time = "2024-07-01T05:40:37.549Z" }, { url = "https://files.pythonhosted.org/packages/6d/10/23c0644cf67567bbe4e3a2eeeec0e9c79b701990c0e07c5ee4a4f8897f91/django_multiselectfield-1.0.1-py3-none-any.whl", hash = "sha256:18dc14801f7eca844a48e21cba6d8ec35b9b581f2373bbb2cb75e6994518259a", size = 20481, upload-time = "2025-06-12T14:41:20.107Z" },
] ]
[[package]] [[package]]
name = "django-soft-delete" name = "django-soft-delete"
version = "1.0.18" version = "1.0.19"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/ec/7e/89cba723dd5d34ccb6003f4812de7f5c69ba32bd73ab37f2bb21ff344c6c/django_soft_delete-1.0.18.tar.gz", hash = "sha256:d2f9db449a4f008e9786f82fa4bafbe4075f7a0b3284844735007e988b2a4df6", size = 11979, upload-time = "2025-02-01T13:43:53.804Z" } sdist = { url = "https://files.pythonhosted.org/packages/ce/77/44a6615a7da3ca0ddc624039d399d17d6c3503e1c2dad08b443f8d4a3570/django_soft_delete-1.0.19.tar.gz", hash = "sha256:c67ee8920e1456eca84cc59b3304ef27fa9d476b516be726ce7e1fc558502908", size = 11993, upload-time = "2025-06-19T20:32:20.373Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/f7/d0/6dcca209e48081213854088fc7014e9dbdcd24f4ec2118f8ee29d11c8623/django_soft_delete-1.0.18-py3-none-any.whl", hash = "sha256:603a29e82bbb7a5bada69f2754fad225ccd8cd7f485320ec06d0fc4e9dfddcf0", size = 10876, upload-time = "2025-02-01T13:43:52.109Z" }, { url = "https://files.pythonhosted.org/packages/96/9e/f8b5a02cdcba606eb40fbe30fe0c9c7493a2c18f83ec3b4620e4e86a34d3/django_soft_delete-1.0.19-py3-none-any.whl", hash = "sha256:46aa5fab513db566d3d7a832529ed27245b5900eaaa705535bc7674055801a46", size = 10889, upload-time = "2025-06-19T20:32:19.083Z" },
] ]
[[package]] [[package]]
@@ -835,28 +835,28 @@ wheels = [
[[package]] [[package]]
name = "djangorestframework" name = "djangorestframework"
version = "3.16.0" version = "3.16.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/7d/97/112c5a72e6917949b6d8a18ad6c6e72c46da4290c8f36ee5f1c1dcbc9901/djangorestframework-3.16.0.tar.gz", hash = "sha256:f022ff46613584de994c0c6a4aebbace5fd700555fbe9d33b865ebf173eba6c9", size = 1068408, upload-time = "2025-03-28T14:18:42.065Z" } sdist = { url = "https://files.pythonhosted.org/packages/8a/95/5376fe618646fde6899b3cdc85fd959716bb67542e273a76a80d9f326f27/djangorestframework-3.16.1.tar.gz", hash = "sha256:166809528b1aced0a17dc66c24492af18049f2c9420dbd0be29422029cfc3ff7", size = 1089735, upload-time = "2025-08-06T17:50:53.251Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/eb/3e/2448e93f4f87fc9a9f35e73e3c05669e0edd0c2526834686e949bb1fd303/djangorestframework-3.16.0-py3-none-any.whl", hash = "sha256:bea7e9f6b96a8584c5224bfb2e4348dfb3f8b5e34edbecb98da258e892089361", size = 1067305, upload-time = "2025-03-28T14:18:39.489Z" }, { url = "https://files.pythonhosted.org/packages/b0/ce/bf8b9d3f415be4ac5588545b5fcdbbb841977db1c1d923f7568eeabe1689/djangorestframework-3.16.1-py3-none-any.whl", hash = "sha256:33a59f47fb9c85ede792cbf88bde71893bcda0667bc573f784649521f1102cec", size = 1080442, upload-time = "2025-08-06T17:50:50.667Z" },
] ]
[[package]] [[package]]
name = "djangorestframework-guardian" name = "djangorestframework-guardian"
version = "0.3.0" version = "0.4.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
{ name = "django-guardian", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "django-guardian", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
{ name = "djangorestframework", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "djangorestframework", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/e5/80/0f2190bacfe7c7b2e22d0e1e695882ec3123f9e58817c8392a258cd46442/djangorestframework-guardian-0.3.0.tar.gz", hash = "sha256:1883756452d9bfcc2a51fb4e039a6837a8f6697c756447aa83af085749b59330", size = 8647, upload-time = "2019-10-14T04:24:25.531Z" } sdist = { url = "https://files.pythonhosted.org/packages/c1/c4/67df9963395e9dddd4e16cbf75098953798e5135f73fb8f4855895505e39/djangorestframework_guardian-0.4.0.tar.gz", hash = "sha256:a8113659e062f65b74cc31af6982420c382642e782d38581b3fdc748a179756c", size = 8239, upload-time = "2025-07-01T07:22:10.809Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/9b/cc/35c1d8fb99172b2646f29e270e9ec443ffe09e0b63e61cd528d4fb4b8b07/djangorestframework_guardian-0.3.0-py2.py3-none-any.whl", hash = "sha256:3bd3dd6ea58e1bceca5048faf6f8b1a93bb5dcff30ba5eb91b9a0e190a48a0c7", size = 6931, upload-time = "2019-08-02T01:00:39.543Z" }, { url = "https://files.pythonhosted.org/packages/59/81/3d62f7ff71f7c45ec6664ebf03a4c736bf77f49481604361d40f8f4471e4/djangorestframework_guardian-0.4.0-py3-none-any.whl", hash = "sha256:30c2a349318c1cd603d6953d50d58159f9a0c833f5f8f5a811407d5984a39e14", size = 6064, upload-time = "2025-07-01T07:22:09.661Z" },
] ]
[[package]] [[package]]
@@ -900,14 +900,14 @@ wheels = [
[[package]] [[package]]
name = "drf-spectacular-sidecar" name = "drf-spectacular-sidecar"
version = "2025.4.1" version = "2025.8.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/5d/b6/ce857d73b65b86a9034d0604b5dc1a002f7fa218e32c4dba479a197acd70/drf_spectacular_sidecar-2025.4.1.tar.gz", hash = "sha256:ea7dc4e674174616589d258b5c9676f3c451ec422e62b79e31234d39db53922d", size = 2402076, upload-time = "2025-04-01T11:23:30.627Z" } sdist = { url = "https://files.pythonhosted.org/packages/a9/f7/0cb2f520723f1823ef7b6651d447927f61ba92d152a5d68132599b90624f/drf_spectacular_sidecar-2025.8.1.tar.gz", hash = "sha256:1944ae0eb5136cff5aa135211bec31084cef1af03a04de9b7f2f912b3c59c251", size = 2407787, upload-time = "2025-08-01T11:28:01.319Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/cf/c3/d2f31ef748f89d68121aa3d4a71f7dfd44ea54957b84602d70cda2491c43/drf_spectacular_sidecar-2025.4.1-py3-none-any.whl", hash = "sha256:343a24b0d03125fa76d07685072f55779c5c4124d90c10b14e315fdc143ad9b9", size = 2422415, upload-time = "2025-04-01T11:23:28.797Z" }, { url = "https://files.pythonhosted.org/packages/1f/3b/0fcdc6eb294a11ed6e3ddc02fc29968bf403d3ce31645764eedfc91f87a6/drf_spectacular_sidecar-2025.8.1-py3-none-any.whl", hash = "sha256:c65a2a423000cc067395150b4dc28e7398a762d66ee101c4c38a4fb0d29a42a2", size = 2427849, upload-time = "2025-08-01T11:27:59.648Z" },
] ]
[[package]] [[package]]
@@ -2050,22 +2050,22 @@ requires-dist = [
{ name = "channels-redis", specifier = "~=4.2" }, { name = "channels-redis", specifier = "~=4.2" },
{ name = "concurrent-log-handler", specifier = "~=0.9.25" }, { name = "concurrent-log-handler", specifier = "~=0.9.25" },
{ name = "dateparser", specifier = "~=1.2" }, { name = "dateparser", specifier = "~=1.2" },
{ name = "django", specifier = "~=5.1.7" }, { name = "django", specifier = "~=5.2.5" },
{ name = "django-allauth", extras = ["socialaccount", "mfa"], specifier = "~=65.4.0" }, { name = "django-allauth", extras = ["socialaccount", "mfa"], specifier = "~=65.4.0" },
{ name = "django-auditlog", specifier = "~=3.1.2" }, { name = "django-auditlog", specifier = "~=3.2.1" },
{ name = "django-cachalot", specifier = "~=2.8.0" }, { name = "django-cachalot", specifier = "~=2.8.0" },
{ name = "django-celery-results", specifier = "~=2.6.0" }, { name = "django-celery-results", specifier = "~=2.6.0" },
{ name = "django-compression-middleware", specifier = "~=0.5.0" }, { name = "django-compression-middleware", specifier = "~=0.5.0" },
{ name = "django-cors-headers", specifier = "~=4.7.0" }, { name = "django-cors-headers", specifier = "~=4.7.0" },
{ name = "django-extensions", specifier = "~=4.1" }, { name = "django-extensions", specifier = "~=4.1" },
{ name = "django-filter", specifier = "~=25.1" }, { name = "django-filter", specifier = "~=25.1" },
{ name = "django-guardian", specifier = "~=2.4.0" }, { name = "django-guardian", specifier = "~=3.0.3" },
{ name = "django-multiselectfield", specifier = "~=0.1.13" }, { name = "django-multiselectfield", specifier = "~=1.0.1" },
{ name = "django-soft-delete", specifier = "~=1.0.18" }, { name = "django-soft-delete", specifier = "~=1.0.18" },
{ name = "djangorestframework", specifier = "~=3.15" }, { name = "djangorestframework", specifier = "~=3.15" },
{ name = "djangorestframework-guardian", specifier = "~=0.3.0" }, { name = "djangorestframework-guardian", specifier = "~=0.4.0" },
{ name = "drf-spectacular", specifier = "~=0.28" }, { name = "drf-spectacular", specifier = "~=0.28" },
{ name = "drf-spectacular-sidecar", specifier = "~=2025.4.1" }, { name = "drf-spectacular-sidecar", specifier = "~=2025.8.1" },
{ name = "drf-writable-nested", specifier = "~=0.7.1" }, { name = "drf-writable-nested", specifier = "~=0.7.1" },
{ name = "filelock", specifier = "~=3.18.0" }, { name = "filelock", specifier = "~=3.18.0" },
{ name = "flower", specifier = "~=2.0.1" }, { name = "flower", specifier = "~=2.0.1" },
@@ -2119,7 +2119,7 @@ dev = [
{ name = "pre-commit-uv", specifier = "~=4.1.3" }, { name = "pre-commit-uv", specifier = "~=4.1.3" },
{ name = "pytest", specifier = "~=8.4.1" }, { name = "pytest", specifier = "~=8.4.1" },
{ name = "pytest-cov", specifier = "~=6.2.1" }, { name = "pytest-cov", specifier = "~=6.2.1" },
{ name = "pytest-django", specifier = "~=4.10.0" }, { name = "pytest-django", specifier = "~=4.11.1" },
{ name = "pytest-env" }, { name = "pytest-env" },
{ name = "pytest-httpx" }, { name = "pytest-httpx" },
{ name = "pytest-mock" }, { name = "pytest-mock" },
@@ -2143,7 +2143,7 @@ testing = [
{ name = "imagehash" }, { name = "imagehash" },
{ name = "pytest", specifier = "~=8.4.1" }, { name = "pytest", specifier = "~=8.4.1" },
{ name = "pytest-cov", specifier = "~=6.2.1" }, { name = "pytest-cov", specifier = "~=6.2.1" },
{ name = "pytest-django", specifier = "~=4.10.0" }, { name = "pytest-django", specifier = "~=4.11.1" },
{ name = "pytest-env" }, { name = "pytest-env" },
{ name = "pytest-httpx" }, { name = "pytest-httpx" },
{ name = "pytest-mock" }, { name = "pytest-mock" },
@@ -2597,14 +2597,14 @@ wheels = [
[[package]] [[package]]
name = "pytest-django" name = "pytest-django"
version = "4.10.0" version = "4.11.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "pytest", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "pytest", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/a5/10/a096573b4b896f18a8390d9dafaffc054c1f613c60bf838300732e538890/pytest_django-4.10.0.tar.gz", hash = "sha256:1091b20ea1491fd04a310fc9aaff4c01b4e8450e3b157687625e16a6b5f3a366", size = 84710, upload-time = "2025-02-10T14:52:57.337Z" } sdist = { url = "https://files.pythonhosted.org/packages/b1/fb/55d580352db26eb3d59ad50c64321ddfe228d3d8ac107db05387a2fadf3a/pytest_django-4.11.1.tar.gz", hash = "sha256:a949141a1ee103cb0e7a20f1451d355f83f5e4a5d07bdd4dcfdd1fd0ff227991", size = 86202, upload-time = "2025-04-03T18:56:09.338Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/58/4c/a4fe18205926216e1aebe1f125cba5bce444f91b6e4de4f49fa87e322775/pytest_django-4.10.0-py3-none-any.whl", hash = "sha256:57c74ef3aa9d89cae5a5d73fbb69a720a62673ade7ff13b9491872409a3f5918", size = 23975, upload-time = "2025-02-10T14:52:55.325Z" }, { url = "https://files.pythonhosted.org/packages/be/ac/bd0608d229ec808e51a21044f3f2f27b9a37e7a0ebaca7247882e67876af/pytest_django-4.11.1-py3-none-any.whl", hash = "sha256:1b63773f648aa3d8541000c26929c1ea63934be1cfa674c76436966d73fe6a10", size = 25281, upload-time = "2025-04-03T18:56:07.678Z" },
] ]
[[package]] [[package]]