diff --git a/.github/workflows/backend-test.yml b/.github/workflows/backend-test.yml index 14d26bee1d..e59ed315bf 100644 --- a/.github/workflows/backend-test.yml +++ b/.github/workflows/backend-test.yml @@ -19,7 +19,7 @@ jobs: services: postgres: - image: postgres:14.5 + image: postgres:18.6 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 4d0b051039..d02405a335 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -34,7 +34,7 @@ jobs: services: postgres: - image: postgres:14.5 + image: postgres:18.6 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres diff --git a/backend/pycon/settings/base.py b/backend/pycon/settings/base.py index a9250d4d8a..cf08e3c0f0 100644 --- a/backend/pycon/settings/base.py +++ b/backend/pycon/settings/base.py @@ -88,6 +88,7 @@ "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", + "django.contrib.postgres", "api.apps.ApiConfig", "timezone_field", "strawberry.django", diff --git a/backend/pyproject.toml b/backend/pyproject.toml index c108a976c9..e5165d46d0 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -43,10 +43,10 @@ known-first-party = [ [project] requires-python = ">=3.14.7" dependencies = [ - "django==5.2.18", + "django==6.1.3", "django-environ==0.14.0", "django-model-utils==5.0.0", - "django-timezone-field==7.0", + "django-timezone-field==7.2.2", "certifi==2026.10.23", "chardet==5.2.0", "idna==3.15", @@ -61,9 +61,9 @@ dependencies = [ "boto3==1.43.34", "pycountry<20.0,>=19.8", "countries<1.0.0,>=0.2.0", - "django-ses==4.1.1", + "django-ses==4.9.0", "hashids<2.0.0,>=1.2.0", - "django-autocomplete-light==3.9.4", + "django-autocomplete-light==4.0.3", "django-queryinspect<2.0.0,>=1.1.0", "lxml==6.1.0", "unidecode<2.0.0,>=1.1.1", @@ -82,8 +82,8 @@ dependencies = [ "stripe==10.5.0", "djangorestframework==3.18.3", "l18n<2022.0,>=2021.3", - "wagtail==7.3.4", - "wagtail-localize==1.13", + "wagtail==8.1", + "wagtail-localize==1.14.5", "celery==5.6.3", "wagtail-headless-preview==0.8.0", "Jinja2>=3.1.6", diff --git a/backend/schedule/admin.py b/backend/schedule/admin.py index 8da7259a46..9b612b47c9 100644 --- a/backend/schedule/admin.py +++ b/backend/schedule/admin.py @@ -64,7 +64,7 @@ def mark_speakers_to_receive_vouchers(modeladmin, request, queryset): .distinct() ) - conference = queryset.only("conference_id").first().conference + conference = queryset.first().conference existing_vouchers: dict[int, ConferenceVoucher.VoucherType] = { user_id: voucher_type diff --git a/backend/schedule/tests/test_admin.py b/backend/schedule/tests/test_admin.py index d571f8a921..0a3a2c263a 100644 --- a/backend/schedule/tests/test_admin.py +++ b/backend/schedule/tests/test_admin.py @@ -27,7 +27,7 @@ pytestmark = pytest.mark.django_db -def test_mark_speakers_to_receive_vouchers(rf, mocker): +def test_mark_speakers_to_receive_vouchers(rf, mocker, admin_superuser): mocker.patch( "conferences.models.conference_voucher.get_random_string", side_effect=[ @@ -54,11 +54,16 @@ def test_mark_speakers_to_receive_vouchers(rf, mocker): conference=conference, submission=None, ) + request = rf.get("/") + request.user = admin_superuser + changelist = ScheduleItemAdmin(ScheduleItem, AdminSite()).get_changelist_instance( + request + ) mark_speakers_to_receive_vouchers( None, - request=rf.get("/"), - queryset=ScheduleItem.objects.filter(conference=conference), + request=request, + queryset=changelist.get_queryset(request).filter(conference=conference), ) assert ConferenceVoucher.objects.count() == 2 diff --git a/backend/uv.lock b/backend/uv.lock index 5c2a60a879..13aa88cd8c 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -382,8 +382,8 @@ requires-dist = [ { name = "countries", specifier = ">=0.2.0,<1.0.0" }, { name = "cryptography", specifier = ">=50.0.0" }, { name = "dal-admin-filters", specifier = "==1.1.0" }, - { name = "django", specifier = "==5.2.18" }, - { name = "django-autocomplete-light", specifier = "==3.9.4" }, + { name = "django", specifier = "==6.1.3" }, + { name = "django-autocomplete-light", specifier = "==4.0.3" }, { name = "django-environ", specifier = "==0.14.0" }, { name = "django-imagekit", specifier = "==6.0.0" }, { name = "django-import-export", extras = ["all"], specifier = ">=4.4.4,<5.0.0" }, @@ -391,9 +391,9 @@ requires-dist = [ { name = "django-model-utils", specifier = "==5.0.0" }, { name = "django-ordered-model", specifier = "==3.5" }, { name = "django-queryinspect", specifier = ">=1.1.0,<2.0.0" }, - { name = "django-ses", specifier = "==4.1.1" }, + { name = "django-ses", specifier = "==4.9.0" }, { name = "django-storages", specifier = "==1.14.6" }, - { name = "django-timezone-field", specifier = "==7.0" }, + { name = "django-timezone-field", specifier = "==7.2.2" }, { name = "djangorestframework", specifier = "==3.18.3" }, { name = "google-api-python-client", specifier = ">=2.94.0,<3.0.0" }, { name = "google-auth", specifier = ">=2.22.0,<3.0.0" }, @@ -432,10 +432,10 @@ requires-dist = [ { name = "unidecode", specifier = ">=1.1.1,<2.0.0" }, { name = "urllib3", specifier = "==2.8.0" }, { name = "uwsgi", specifier = "==2.0.30" }, - { name = "wagtail", specifier = "==7.3.4" }, + { name = "wagtail", specifier = "==8.1" }, { name = "wagtail-factories", specifier = "==4.4.0" }, { name = "wagtail-headless-preview", specifier = "==0.8.0" }, - { name = "wagtail-localize", specifier = "==1.13" }, + { name = "wagtail-localize", specifier = "==1.14.5" }, { name = "weasyprint", specifier = ">=68.0" }, { name = "werkzeug", specifier = ">=1.0.1,<4.0.0" }, { name = "whitenoise", specifier = "==6.12.0" }, @@ -1053,16 +1053,16 @@ wheels = [ [[package]] name = "django" -version = "5.2.18" +version = "6.1.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "asgiref" }, { name = "sqlparse" }, { name = "tzdata", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/85/fe/79e692b430c7721bf4b812c328bfe687e73e3f28f56611a6a18a97e887cc/django-5.2.18.tar.gz", hash = "sha256:461c5dd06d2ea16bd5ca37d3f46e4def1d6b0fe7588c6f4e2119517bb0af8b2d", size = 10910238, upload-time = "2026-10-06T13:01:09.371Z" } +sdist = { url = "https://files.pythonhosted.org/packages/55/79/49a609ea76ec51404b482932e33f1e6858946b920232c11b11a25bea3032/django-6.1.3.tar.gz", hash = "sha256:b5d2d9e35295065d13b1927b3f19a59bd119f737aa6299def14ccca1ae3c8c0d", size = 11306257, upload-time = "2026-11-03T15:21:26.142Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d6/01/6568ec52b26548ca1b83d33249f7274db3bf74698f42c0da42ec9db1a24a/django-5.2.18-py3-none-any.whl", hash = "sha256:92ed81d500be6408ecd704d7bd1366c534f30427bffcc63c5fefb129561aec7c", size = 8316071, upload-time = "2026-10-06T13:01:04.413Z" }, + { url = "https://files.pythonhosted.org/packages/77/f2/adbe0352c6673f7b608724be5f69962c80ba1d06f8ed60fa4bfbec258b08/django-6.1.3-py3-none-any.whl", hash = "sha256:a0530e3fdac55d34ccc5893c36f6c57d7a7083064f3d414537e51473648b3290", size = 8424610, upload-time = "2026-11-03T15:21:19.64Z" }, ] [[package]] @@ -1079,12 +1079,15 @@ wheels = [ [[package]] name = "django-autocomplete-light" -version = "3.9.4" +version = "4.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "six" }, + { name = "django" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/5d/0f1f1884cfa5665a20a89497c80fc10726f47d982905c8e36e9ef31cc7e6/django_autocomplete_light-4.0.3.tar.gz", hash = "sha256:1b0dc31aee64cc084358129df60954c05ab7132657873eebc0612e3160307057", size = 99685, upload-time = "2026-06-18T11:55:02.581Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/fa/299a37e7a4baf7bec9c002e4bd1f46cc6e5db8565d8f9883407d471cf2df/django_autocomplete_light-4.0.3-py3-none-any.whl", hash = "sha256:e36a7c570f914cfd793568eea3eb2646da4b64f6d1cd3bea8878cc8b20a18f3f", size = 113477, upload-time = "2026-06-18T11:55:00.869Z" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ae/72/6a6c2d4b05296c9248a1e95430fa4f4605c210c2fac1d7d80d9e7bdf90f0/django-autocomplete-light-3.9.4.tar.gz", hash = "sha256:0f6da75c1c7186698b867a467a8cdb359f0513fdd8e09288a0c2fb018ae3d94e", size = 168936, upload-time = "2022-03-15T08:44:50.603Z" } [[package]] name = "django-debug-toolbar" @@ -1190,6 +1193,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cd/57/cdcdea9a56d114e9217d52ce9a8af19ad7fe8a0996faf8480d3f286c02e0/django_modelcluster-6.5-py3-none-any.whl", hash = "sha256:469b380a294027d5211d0e5d5746e0381f445b058d2229977a58fe0f1c58a596", size = 29865, upload-time = "2026-05-01T12:25:31.886Z" }, ] +[[package]] +name = "django-ninja" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "django" }, + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8d/53/3453836e6246b5d4b0e55c36d2dfab4cad6091d08483bdc4505906a1197c/django_ninja-1.8.0.tar.gz", hash = "sha256:0f043a1aebd2c45e2a124a83e5bd0961491b18cdf81ea57c6abd80607b2c6ef8", size = 2347023, upload-time = "2026-11-08T10:52:03.703Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/d5/fbfdae4ab7a81f4980cec09ef17f86d4ac2d96058787bd6282d775be91bc/django_ninja-1.8.0-py3-none-any.whl", hash = "sha256:132f37a36ac5ec9569fdc141da6984c1806bdd08af36f855980fab6cdcb10038", size = 2382930, upload-time = "2026-11-08T10:52:01.541Z" }, +] + [[package]] name = "django-ordered-model" version = "3.5" @@ -1222,15 +1238,15 @@ sdist = { url = "https://files.pythonhosted.org/packages/77/bb/6cb5fb15f27312660 [[package]] name = "django-ses" -version = "4.1.1" +version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "boto3" }, { name = "django" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/80/aa/d0237d9b093c1d671b8c8c7e498c9526af47cc7f4fa7cfc1dc22cb1179c8/django_ses-4.1.1.tar.gz", hash = "sha256:28f9931df1251660eaf976b7413a42e7b0d25a18043316b96c721d8add7bf7b8", size = 47491, upload-time = "2024-08-22T18:26:40.206Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b4/17/b116bb293964d54406b9d4337514f8053886eb66bbb42958286135ae71cd/django_ses-4.9.0.tar.gz", hash = "sha256:d1aa855d8415bb9991fc1fa427dd31a5bb55b98e27c1b19b973566b70a6e83dd", size = 79421, upload-time = "2026-10-29T23:59:48.57Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/6a/de24558d93fe778a8d98bcf3817fa535011250f35ce95d5add7b739bd441/django_ses-4.1.1-py3-none-any.whl", hash = "sha256:83bb09d2b149dbc1a67a89f66a6681a99e32b8253f47ff4b7fae241d05344cc8", size = 29543, upload-time = "2024-08-22T18:26:37.859Z" }, + { url = "https://files.pythonhosted.org/packages/2c/b9/28547a2f22e3ee3d5db1b3935462df2e4a62f9fb48fc01f0d111bc0ec424/django_ses-4.9.0-py3-none-any.whl", hash = "sha256:34e9f6f13b3ebd8618cfd8d9f93d75f40d6dc5a896a1b3ffa48c4054be75fbe5", size = 40891, upload-time = "2026-10-29T23:59:46.923Z" }, ] [[package]] @@ -1286,14 +1302,14 @@ wheels = [ [[package]] name = "django-timezone-field" -version = "7.0" +version = "7.2.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "django" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/94/b3/992aa517b95f2e6934aa05b8160cf55f91c49c7b91e33076ea9af2f29920/django_timezone_field-7.0.tar.gz", hash = "sha256:aa6f4965838484317b7f08d22c0d91a53d64e7bbbd34264468ae83d4023898a7", size = 13683, upload-time = "2024-07-07T18:32:06.941Z" } +sdist = { url = "https://files.pythonhosted.org/packages/12/0b/22654abc2355f3b84e3e5b9d26569639c15d04b96d7186f3a477ec45c1ef/django_timezone_field-7.2.2.tar.gz", hash = "sha256:a004d0b19fe10bf5964cb21a65b36324b16a61879e4711c0dafdf8d6253e8ebc", size = 13158, upload-time = "2026-06-06T05:28:23.638Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/f9/11769c4414026f1a9ce3e581731d07b084683fc7b4c580703dc71ef81347/django_timezone_field-7.0-py3-none-any.whl", hash = "sha256:3232e7ecde66ba4464abb6f9e6b8cc739b914efb9b29dc2cf2eee451f7cc2acb", size = 13161, upload-time = "2024-07-07T18:32:04.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/5f/c8dfb67105c4ef391a3e9d0bcd35b7eae4c4c9d023d612c3999ae1cb32ef/django_timezone_field-7.2.2-py3-none-any.whl", hash = "sha256:30354d0f37462a0b9b5c289e271580a6be9b58dea30e7bf88435372882c8fa7a", size = 13322, upload-time = "2026-06-06T05:28:22.454Z" }, ] [[package]] @@ -1322,11 +1338,11 @@ wheels = [ [[package]] name = "draftjs-exporter" -version = "5.2.0" +version = "7.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4f/61/8b7fab482ef246f931b57f55f370e68377a53dcf5259f3fcf01e4889d4af/draftjs_exporter-5.2.0.tar.gz", hash = "sha256:4d665f8c75fd173d2c99326405300e8defcf4961b9b2f16ff117486489c6760b", size = 19674, upload-time = "2026-01-02T14:19:38.17Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a5/cd/f6e8e34690eccd80e551b39a64e81ce22a1b82422a4384d346ba8c1d5b45/draftjs_exporter-7.3.1.tar.gz", hash = "sha256:557e2afb861f9447c8d503089ec140e45e1bbfb4acdce745e589291f117dac93", size = 60638, upload-time = "2026-10-20T07:03:58.069Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/53/e1/2f81aa30ba22ceabb6779ed5dbd6b27fbf6f28deabad91140d1a32f3da5b/draftjs_exporter-5.2.0-py3-none-any.whl", hash = "sha256:f5255510a9c1de60807c1ba4be9666fb44ba263841b63329c8ce70d66146764c", size = 26251, upload-time = "2026-01-02T14:19:36.843Z" }, + { url = "https://files.pythonhosted.org/packages/5e/b3/91c4b92c67afbc70856911467ec6d239e5f0fa0f91974b7a415f168f29fb/draftjs_exporter-7.3.1-py3-none-any.whl", hash = "sha256:eddd07ee418c5f85c6a2900887fa1eb50de0c5f6533193497b1fe063803210e9", size = 75306, upload-time = "2026-10-20T07:03:56.69Z" }, ] [[package]] @@ -2244,15 +2260,15 @@ wheels = [ [[package]] name = "modelsearch" -version = "1.2.2" +version = "1.3.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "django" }, { name = "django-tasks" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a2/7f/f775ea3ea2180a39fda4fb9bcce634478fc844ab0f436b899cc0a6e7a1c6/modelsearch-1.2.2.tar.gz", hash = "sha256:59fc29965d5411d607d0d5f80a65f0f49bec54bd5a425e8e0bfb185f04761e5b", size = 91157, upload-time = "2026-04-27T23:36:56.311Z" } +sdist = { url = "https://files.pythonhosted.org/packages/77/e3/5ce9c70828fe46be161781a04860fe3fe9d54c9b0b09539d9c291d15dbcf/modelsearch-1.3.2.tar.gz", hash = "sha256:52ede0f65e91efdb9d715f603e0bb3db96a95c80eba695abcd4628c03759999e", size = 105253, upload-time = "2026-08-11T14:38:12.199Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d3/03/24e5c5af6962e85fddebb58ba8448109789f62fee61b8375161284aa8e33/modelsearch-1.2.2-py3-none-any.whl", hash = "sha256:fd18522c1619e00452266513a78284a4e5016871c107036b078a45e42fa871e2", size = 111491, upload-time = "2026-04-27T23:36:54.712Z" }, + { url = "https://files.pythonhosted.org/packages/6a/46/394e799ff69475093f05187929618b13cb230e9e9ce358313a1055724a5d/modelsearch-1.3.2-py3-none-any.whl", hash = "sha256:8738ad7dc6fd2f70f622e717c52fbdcc60285e6b74acc41a7bf3fe911718532b", size = 129677, upload-time = "2026-08-11T14:38:10.768Z" }, ] [[package]] @@ -3773,6 +3789,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/63/8a/677210793a870dd399f0fbdd0b67085b11681a5d5f5c2b020248ac9df790/stripe-10.5.0-py2.py3-none-any.whl", hash = "sha256:682399995c27cb1dbfecda11f85b1ff3bd96a11a689419bf6156075cd7823099", size = 1541397, upload-time = "2024-07-25T21:06:58.559Z" }, ] +[[package]] +name = "swapper" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c2/3e/a28d29aa28570b09257dad52cc5e5ebda9fe8802eeca0d9e254ccf8e5788/swapper-1.5.0.tar.gz", hash = "sha256:405f934265aa0c8d8b8e6b1be584875d1a3b7de6b1cd6f47367a4dbdc028609a", size = 24119, upload-time = "2026-09-01T21:51:07.192Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/29/5f/eab0a39f9c16c5d32c00f1f9b7ee9e8823686d1fd40a7fd1f0fc3247a59c/swapper-1.5.0-py2.py3-none-any.whl", hash = "sha256:67ae5a01bc12159dede567b98212a83baa53aa466a8eb5cf44af226b8219d21c", size = 7273, upload-time = "2026-09-01T21:51:05.953Z" }, +] + [[package]] name = "sympy" version = "1.14.0" @@ -4137,7 +4162,7 @@ wheels = [ [[package]] name = "wagtail" -version = "7.3.4" +version = "8.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyascii" }, @@ -4145,6 +4170,7 @@ dependencies = [ { name = "django" }, { name = "django-filter" }, { name = "django-modelcluster" }, + { name = "django-ninja" }, { name = "django-permissionedforms" }, { name = "django-taggit" }, { name = "django-tasks" }, @@ -4155,13 +4181,15 @@ dependencies = [ { name = "modelsearch" }, { name = "openpyxl" }, { name = "pillow" }, + { name = "pydantic" }, { name = "requests" }, + { name = "swapper" }, { name = "telepath" }, { name = "willow", extra = ["heif"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/00/3f/5731e6010db528b5e4da201e65f67703c89770e5be6be49b5a1ea4c42876/wagtail-7.3.4.tar.gz", hash = "sha256:30816255dfbb97238050a6687f04b2b4eb88f5201993c48df36d68fab0a70505", size = 6897983, upload-time = "2026-08-20T15:28:10.932Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7f/f4/b610c5f9e26b43fc404045800a2a3d167e2b055e69837f4ebf3331f78c07/wagtail-8.1.tar.gz", hash = "sha256:5c1abb0e11efc31454db0b5312d6786b5d8fdfbef5c815b7d8bacb2ad6bd486c", size = 7073619, upload-time = "2026-11-02T15:58:35.52Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/63/c34864d49075491157c5215a827406b5663d6025710b3eea00b99592f791/wagtail-7.3.4-py3-none-any.whl", hash = "sha256:2eab9f6a872b967a55f2575a38b4f83a3d406a34d5dab456e0a21c91fd57bcca", size = 9492859, upload-time = "2026-08-20T15:28:00.066Z" }, + { url = "https://files.pythonhosted.org/packages/15/9d/76d9a648ae7fe34425b474be23d9e0bef43f2f332d848a0d2e865c042564/wagtail-8.1-py3-none-any.whl", hash = "sha256:dd7c988377ec6b8fcbd9ea8b5e36d34d800706bb70f927711ff4575619752d42", size = 9756355, upload-time = "2026-11-02T15:57:51.495Z" }, ] [[package]] @@ -4191,7 +4219,7 @@ wheels = [ [[package]] name = "wagtail-localize" -version = "1.13" +version = "1.14.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "django" }, @@ -4199,9 +4227,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "wagtail" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6c/19/781b910e3ee3b1f955376efe92c6f192e8e43130dd2ec892592aaac27073/wagtail_localize-1.13.tar.gz", hash = "sha256:48ecfcd6d002009697b84d77ebcb042451a68da916a1f5ca0e161b472c2b74c8", size = 285949, upload-time = "2026-01-25T16:46:42.592Z" } +sdist = { url = "https://files.pythonhosted.org/packages/50/09/edc4a6a17edcdf78d2a5bf8395e68f991c709d101aad0ce4fc636b0f9ef0/wagtail_localize-1.14.5.tar.gz", hash = "sha256:7e21bb845bd0142a554a8ddb5819450782107dac94756a90f56085991a4c318d", size = 1189851, upload-time = "2026-08-19T15:11:22.001Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/27/ab/18535934b8503000ef0bcd892f505f728a44cbb9499ae3d4e052647e1ef9/wagtail_localize-1.13-py3-none-any.whl", hash = "sha256:48296cb90eb3317bea62ecd5f23cc57088c9c9d39aca3b2261e4f19fa15de2cf", size = 511068, upload-time = "2026-01-25T16:46:40.628Z" }, + { url = "https://files.pythonhosted.org/packages/27/64/59c70f0c48e37bcec2706963adbe5a577e178bdf56790f10e581ffff8f35/wagtail_localize-1.14.5-py3-none-any.whl", hash = "sha256:c08841d1d982e238b4cf5fb8e5d4cace82cf8e8d255fd0db4fa11dd874d7c0fd", size = 535341, upload-time = "2026-08-19T15:11:20.441Z" }, ] [[package]] diff --git a/backend/voting/admin.py b/backend/voting/admin.py index 6592517d89..9f7ed97962 100644 --- a/backend/voting/admin.py +++ b/backend/voting/admin.py @@ -16,6 +16,11 @@ class SubmissionFilter(AutocompleteFilter): field_name = "submission" autocomplete_url = "submission-autocomplete" + def get_queryset_for_field(self, model, name): + # dal_admin_filters calls the FK descriptor's get_queryset() without the + # `instance` argument Django requires. + return model._meta.get_field(name).related_model._base_manager.all() + class ConferenceFilter(AutocompleteFilter): title = "Conference" diff --git a/backend/voting/tests/test_admin.py b/backend/voting/tests/test_admin.py index e620baa175..a5061d2ef1 100644 --- a/backend/voting/tests/test_admin.py +++ b/backend/voting/tests/test_admin.py @@ -1,13 +1,26 @@ import pytest +from django.contrib import admin from i18n.strings import LazyI18nString -from voting.admin import RankSubmissionResource -from voting.models import RankSubmission +from voting.admin import RankSubmissionResource, VoteAdmin +from voting.models import RankSubmission, Vote from voting.tests.factories.ranking import RankSubmissionFactory +from voting.tests.factories.vote import VoteFactory pytestmark = pytest.mark.django_db +def test_vote_changelist_filters_by_submission(rf, admin_superuser): + vote = VoteFactory() + VoteFactory() + request = rf.get("/", {"submission__id__exact": vote.submission_id}) + request.user = admin_superuser + + changelist = VoteAdmin(Vote, admin.site).get_changelist_instance(request) + + assert list(changelist.queryset) == [vote] + + def test_rank_submission_export_includes_submission_title(): RankSubmissionFactory(submission__title=LazyI18nString({"en": "My talk"}))