Skip to content

Commit fa385bd

Browse files
authored
fix: Compatibility with custom images (#1454)
* Made the filer check command compatible with custom image models * Use the final image model's app label to determine the expand view URL * Prepare the image expand URL in the admin code and pass it through to the template via context * Added tests for the new expand link handling * Added runs with a custom image model to the test matrix for GitHub actions * Added packaging to requirements
1 parent b0f39ab commit fa385bd

File tree

8 files changed

+64
-17
lines changed

8 files changed

+64
-17
lines changed

.github/workflows/test.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ jobs:
88
strategy:
99
fail-fast: false
1010
matrix:
11-
python-version: ['3.8', '3.9', '3.10', '3.11' ]
11+
python-version: ['3.8', '3.9', '3.10', '3.11']
1212
requirements-file: [
1313
django-3.2.txt,
1414
django-4.0.txt,
1515
django-4.1.txt,
1616
django-4.2.txt,
1717
django-5.0.txt,
1818
]
19+
custom-image-model: [false, true]
1920
exclude:
2021
- requirements-file: django-5.0.txt
2122
python-version: 3.8
@@ -41,8 +42,10 @@ jobs:
4142
python -m pip install --upgrade pip
4243
pip install -r tests/requirements/${{ matrix.requirements-file }}
4344
python setup.py install
45+
- name: Enable the custom image model
46+
run: echo "CUSTOM_IMAGE=custom_image.Image" >> $GITHUB_ENV
47+
if: ${{ matrix.custom-image-model }}
4448
- name: Run coverage
4549
run: coverage run setup.py test
46-
4750
- name: Upload Coverage to Codecov
4851
uses: codecov/codecov-action@v1

filer/admin/fileadmin.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import mimetypes
22

33
from django import forms
4+
from django.contrib.admin.templatetags.admin_urls import admin_urlname
45
from django.contrib.admin.utils import unquote
56
from django.contrib.staticfiles.storage import staticfiles_storage
67
from django.http import Http404, HttpResponse, HttpResponseRedirect
@@ -19,10 +20,14 @@
1920
from .. import settings
2021
from ..models import BaseImage, File
2122
from ..settings import DEFERRED_THUMBNAIL_SIZES
23+
from ..utils.loader import load_model
2224
from .permissions import PrimitivePermissionAwareModelAdmin
2325
from .tools import AdminContext, admin_url_params_encoded, popup_status
2426

2527

28+
Image = load_model(settings.FILER_IMAGE_MODEL)
29+
30+
2631
class FileAdminChangeFrom(forms.ModelForm):
2732
class Meta:
2833
model = File
@@ -123,12 +128,18 @@ def response_change(self, request, obj):
123128

124129
def render_change_form(self, request, context, add=False, change=False,
125130
form_url='', obj=None):
126-
info = self.model._meta.app_label, self.model._meta.model_name
127-
extra_context = {'show_delete': True,
128-
'history_url': 'admin:%s_%s_history' % info,
129-
'is_popup': popup_status(request),
130-
'filer_admin_context': AdminContext(request)}
131-
context.update(extra_context)
131+
context.update({
132+
'show_delete': True,
133+
'history_url': admin_urlname(self.opts, 'history'),
134+
'expand_image_url': None,
135+
'is_popup': popup_status(request),
136+
'filer_admin_context': AdminContext(request),
137+
})
138+
if obj and obj.mime_maintype == 'image' and obj.file.exists():
139+
if 'svg' in obj.mime_type:
140+
context['expand_image_url'] = reverse(admin_urlname(Image._meta, 'expand'), args=(obj.pk,))
141+
else:
142+
context['expand_image_url'] = obj.file.url
132143
return super().render_change_form(
133144
request=request, context=context, add=add, change=change,
134145
form_url=form_url, obj=obj)

filer/admin/imageadmin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def get_urls(self):
9191
return super().get_urls() + [
9292
path("expand/<int:file_id>",
9393
self.admin_site.admin_view(self.expand_view),
94-
name=f"filer_{self.model._meta.model_name}_expand_view")
94+
name=f"{self.opts.app_label}_{self.opts.model_name}_expand")
9595
]
9696

9797
def expand_view(self, request, file_id):

filer/management/commands/filer_check.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from PIL import UnidentifiedImageError
88

99
from filer import settings as filer_settings
10+
from filer.utils.loader import load_model
1011

1112

1213
class Command(BaseCommand):
@@ -130,10 +131,9 @@ def image_dimensions(self, options):
130131
import easy_thumbnails
131132
from easy_thumbnails.VIL import Image as VILImage
132133

133-
from filer.models.imagemodels import Image
134134
from filer.utils.compatibility import PILImage
135135

136-
no_dimensions = Image.objects.filter(
136+
no_dimensions = load_model(filer_settings.FILER_IMAGE_MODEL).objects.filter(
137137
Q(_width=0) | Q(_width__isnull=True)
138138
)
139139
self.stdout.write(f"trying to set dimensions on {no_dimensions.count()} files")

filer/templates/admin/filer/tools/detail_info.html

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@
1010
<span class="icon fa fa-download filer-icon filer-icon-download"></span>&nbsp;
1111
<span>{% translate "Download" %}</span>
1212
</a>
13-
{% if original.mime_maintype == 'image' %}
14-
<a href="{% if 'svg' in original.mime_type %}{% url 'admin:filer_image_expand_view' original.pk %}{% else %}{{ original.file.url }}{% endif %}"
15-
target="_blank" rel="noopener noreferrer" class="button">
13+
{% if expand_image_url %}
14+
<a href="{{ expand_image_url }}" target="_blank" rel="noopener noreferrer" class="button">
1615
<span>{% translate "Expand" %}</span>&nbsp;
1716
<span class="icon filer-icon filer-icon-expand fa fa-expand"></span>
1817
</a>

tests/requirements/base.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ django-app-helper>=3.3.1
77
coverage
88
isort
99
flake8
10+
packaging

tests/test_admin.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from django.conf import settings
77
from django.contrib import admin
88
from django.contrib.admin import helpers
9+
from django.contrib.admin.templatetags.admin_urls import admin_urlname
910
from django.contrib.auth import get_user_model
1011
from django.contrib.auth.models import Permission
1112
from django.contrib.messages import ERROR, get_messages
@@ -327,7 +328,7 @@ def test_detail_view_missing_file(self):
327328
image._height = 200
328329
image.save()
329330

330-
url = reverse(f'admin:{image.__class__._meta.app_label}_image_change', kwargs={
331+
url = reverse(admin_urlname(Image._meta, 'change'), kwargs={
331332
'object_id': image.pk,
332333
})
333334

@@ -338,8 +339,36 @@ def test_detail_view_missing_file(self):
338339
self.assertContains(response, 'height="210"')
339340
self.assertContains(response, 'alt="File is missing"')
340341

342+
def test_image_expand_link_in_change_view(self):
343+
files = [
344+
# Files can use the same contents for this test - it's the mime type that counts
345+
File.objects.create(owner=self.superuser, original_filename='some-file.txt', file=self.file_object.file),
346+
Image.objects.create(owner=self.superuser, original_filename='some-image.jpg'), # missing file
347+
Image.objects.create(owner=self.superuser, original_filename='some-image.jpg', file=self.file_object.file),
348+
Image.objects.create(owner=self.superuser, original_filename='some-image.svg', file=self.file_object.file),
349+
]
350+
test_set = [
351+
(files[0], 'text/plain', None),
352+
(files[1], 'image/jpeg', None),
353+
(files[2], 'image/jpeg', files[2].file.url),
354+
(files[3], 'image/svg+xml', reverse(admin_urlname(Image._meta, 'expand'), args=(files[3].pk,))),
355+
]
356+
for file, mime_type, expected_url in test_set:
357+
file.mime_type = mime_type
358+
file.save()
359+
models = [File]
360+
if isinstance(file, Image):
361+
models.append(Image)
362+
for model in models:
363+
response = self.client.get(reverse(admin_urlname(model._meta, 'change'),
364+
kwargs={'object_id': file.pk}))
365+
if expected_url:
366+
self.assertContains(response, f'href="{expected_url}"')
367+
else:
368+
self.assertNotContains(response, 'filer-icon-expand')
369+
341370
def test_image_expand_view(self):
342-
url = reverse("admin:filer_image_expand_view", kwargs={
371+
url = reverse(admin_urlname(Image._meta, 'expand'), kwargs={
343372
'file_id': self.file_object.pk
344373
})
345374
original_url = self.file_object.url

tests/test_filer_check.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@
99

1010
from filer import settings as filer_settings
1111
from filer.models.filemodels import File
12-
from filer.models.imagemodels import Image
12+
from filer.settings import FILER_IMAGE_MODEL
13+
from filer.utils.loader import load_model
1314
from tests.helpers import create_image
1415

1516

17+
Image = load_model(FILER_IMAGE_MODEL)
18+
19+
1620
class FilerCheckTestCase(TestCase):
1721

1822
svg_file_string = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>

0 commit comments

Comments
 (0)