Skip to content

Commit 5e46265

Browse files
authored
fix: Remove user from autocomplete fields if (swapped) user model does not have search fields (#1517)
* fix: Remove user from autocomplete fields if (swapped) user model does not have search fields * Ensure Django 4.2 support * Fix github action * Use correct Django Version * Refactor for better DRY * Update test.yml * Update tests * Fix other log deletions * Simplify deletion of folders * Undo unwanted change
1 parent c610365 commit 5e46265

File tree

7 files changed

+77
-22
lines changed

7 files changed

+77
-22
lines changed

.github/workflows/test.yml

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,31 @@ jobs:
88
strategy:
99
fail-fast: false
1010
matrix:
11-
python-version: [3.8, 3.9, '3.10', '3.11', '3.12']
11+
python-version: [3.9, '3.10', '3.11', '3.12', '3.13']
1212
requirements-file: [
1313
django-4.2.txt,
1414
django-5.0.txt,
1515
django-5.1.txt,
16+
django-5.2.txt,
1617
django-main.txt,
1718
]
1819
custom-image-model: [false, true]
1920
os: [
20-
ubuntu-20.04,
21+
ubuntu-latest,
2122
]
2223
exclude:
23-
- requirements-file: django-5.0.txt
24-
python-version: 3.8
2524
- requirements-file: django-5.0.txt
2625
python-version: 3.9
27-
- requirements-file: django-5.1.txt
28-
python-version: 3.8
2926
- requirements-file: django-5.1.txt
3027
python-version: 3.9
31-
- requirements-file: django-main.txt
32-
python-version: 3.8
28+
- requirements-file: django-5.2.txt
29+
python-version: 3.9
3330
- requirements-file: django-main.txt
3431
python-version: 3.9
32+
- requirements-file: django-main.txt
33+
python-version: 3.10
34+
- requirements-file: django-main.txt
35+
python-version: 3.11
3536

3637
steps:
3738
- uses: actions/checkout@v1
@@ -40,7 +41,7 @@ jobs:
4041
with:
4142
python-version: ${{ matrix.python-version }}
4243
- name: library prerequisites
43-
run: sudo apt-get install python-dev libpq-dev libmagic1 gcc libxml2-dev libxslt1-dev libjpeg62 libopenjp2-7 -y
44+
run: sudo apt-get install python-dev-is-python3 libpq-dev libmagic1 gcc libxml2-dev libxslt1-dev libjpeg62 libopenjp2-7 -y
4445
- name: Install extra dependencies
4546
run: pip install lxml
4647
if: matrix.python-version == '3.10'
@@ -53,6 +54,6 @@ jobs:
5354
run: echo "CUSTOM_IMAGE=custom_image.Image" >> $GITHUB_ENV
5455
if: ${{ matrix.custom-image-model }}
5556
- name: Run coverage
56-
run: coverage run ./tests/settings.py
57+
run: coverage run ./tests/settings.py
5758
- name: Upload Coverage to Codecov
5859
uses: codecov/codecov-action@v1

filer/admin/fileadmin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class FileAdmin(PrimitivePermissionAwareModelAdmin):
6060
list_display = ('label',)
6161
list_per_page = 10
6262
search_fields = ['name', 'original_filename', 'sha1', 'description']
63-
autocomplete_fields = ('owner',)
63+
autocomplete_fields = ['owner']
6464
readonly_fields = ('sha1', 'display_canonical')
6565

6666
form = FileAdminChangeFrom

filer/admin/folderadmin.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from urllib.parse import quote as urlquote
66
from urllib.parse import unquote as urlunquote
77

8+
from django import VERSION as DJANGO_VERSION
89
from django import forms
910
from django.conf import settings as django_settings
1011
from django.contrib import messages
@@ -777,9 +778,15 @@ def delete_files_or_folders(self, request, files_queryset, folders_queryset):
777778
n = files_queryset.count() + folders_queryset.count()
778779
if n:
779780
# delete all explicitly selected files
780-
for f in files_queryset:
781-
self.log_deletion(request, f, force_str(f))
782-
f.delete()
781+
if DJANGO_VERSION >= (5, 1):
782+
self.log_deletions(request, files_queryset)
783+
# Still need to delete files individually (not only the database entries)
784+
for f in files_queryset:
785+
f.delete()
786+
else:
787+
for f in files_queryset:
788+
self.log_deletion(request, f, force_str(f))
789+
f.delete()
783790
# delete all files in all selected folders and their children
784791
# This would happen automatically by ways of the delete
785792
# cascade, but then the individual .delete() methods won't be
@@ -788,13 +795,24 @@ def delete_files_or_folders(self, request, files_queryset, folders_queryset):
788795
for folder in folders_queryset:
789796
folder_ids.add(folder.id)
790797
folder_ids.update(folder.get_descendants_ids())
791-
for f in File.objects.filter(folder__in=folder_ids):
792-
self.log_deletion(request, f, force_str(f))
793-
f.delete()
798+
if DJANGO_VERSION >= (5, 1):
799+
qs = File.objects.filter(folder__in=folder_ids)
800+
self.log_deletions(request, qs)
801+
# Still need to delete files individually (not only the database entries)
802+
for f in qs:
803+
f.delete()
804+
else:
805+
for f in File.objects.filter(folder__in=folder_ids):
806+
self.log_deletion(request, f, force_str(f))
807+
f.delete()
794808
# delete all folders
795-
for f in folders_queryset:
796-
self.log_deletion(request, f, force_str(f))
797-
f.delete()
809+
if DJANGO_VERSION >= (5, 1):
810+
self.log_deletions(request, files_queryset)
811+
folders_queryset.delete()
812+
else:
813+
for f in folders_queryset:
814+
self.log_deletion(request, f, force_str(f))
815+
f.delete()
798816
self.message_user(request, _("Successfully deleted %(count)d files and/or folders.") % {"count": n, })
799817
# Return None to display the change list page again.
800818
return None

filer/admin/permissionadmin.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
from django import VERSION as django_version
12
from django.contrib import admin
3+
from django.contrib.auth import get_user_model
24
from django.utils.translation import gettext_lazy as _
35

46
from .. import settings
@@ -19,6 +21,18 @@ class PermissionAdmin(admin.ModelAdmin):
1921
class Media:
2022
css = {'all': ['filer/css/admin_folderpermissions.css']}
2123

24+
def get_autocomplete_fields(self, request):
25+
"""Remove "owner" from autocomplete_fields is User model has no search_fields"""
26+
27+
autocomplete_fields = super().get_autocomplete_fields(request)
28+
if django_version >= (5, 0):
29+
user_admin = self.admin_site.get_model_admin(get_user_model())
30+
else:
31+
user_admin = self.admin_site._registry[get_user_model()]
32+
if not user_admin.get_search_fields(request):
33+
autocomplete_fields.remove('user')
34+
return autocomplete_fields
35+
2236
def get_queryset(self, request):
2337
qs = super().get_queryset(request)
2438
return qs.prefetch_related("group", "folder")

filer/admin/permissions.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
1+
from django import VERSION as django_version
12
from django.contrib import admin
3+
from django.contrib.auth import get_user_model
24
from django.urls import reverse
35

46

57
class PrimitivePermissionAwareModelAdmin(admin.ModelAdmin):
8+
def get_autocomplete_fields(self, request):
9+
"""Remove "owner" from autocomplete_fields is User model has no search_fields"""
10+
11+
autocomplete_fields = super().get_autocomplete_fields(request)
12+
if django_version >= (5, 0):
13+
user_admin = self.admin_site.get_model_admin(get_user_model())
14+
else:
15+
user_admin = self.admin_site._registry[get_user_model()]
16+
if not user_admin.get_search_fields(request) and 'owner' in autocomplete_fields:
17+
autocomplete_fields.remove('owner')
18+
return autocomplete_fields
19+
620
def has_add_permission(self, request):
721
# we don't have a "add" permission... but all adding is handled
822
# by special methods that go around these permissions anyway

tests/requirements/django-5.2.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-r base.txt
2+
3+
django>=5.2a1,<5.3
4+
django_polymorphic>=3.1

tox.ini

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ envlist =
44
isort
55
docs
66
frontend
7-
py{310,311,312}-{dj42,dj50,djmain}-{swap,noswap}
7+
py{310,311,312}-{dj42,dj50,dj51,dj52}-{swap,noswap}
8+
py{312,313,312}-{djmain}-{swap,noswap}
89

910
[gh-actions]
1011
python =
1112
3.10: py310
1213
3.11: py311
1314
3.12: py312
15+
3.13: py313
1416

1517
skip_missing_interpreters=True
1618

@@ -21,11 +23,13 @@ allowlist_externals =
2123
deps =
2224
dj42: -r tests/requirements/django-4.2.txt
2325
dj50: -r tests/requirements/django-5.0.txt
26+
dj51: -r tests/requirements/django-5.1.txt
27+
dj52: -r tests/requirements/django-5.2.txt
2428
djmain: -r tests/requirements/django-main.txt
2529
commands =
2630
{envpython} --version
2731
{env:COMMAND:coverage} erase
28-
{env:COMMAND:coverage} run setup.py test
32+
{env:COMMAND:coverage} run tests/settings.py
2933
{env:COMMAND:coverage} report
3034
setenv =
3135
swap: CUSTOM_IMAGE=custom_image.Image

0 commit comments

Comments
 (0)