Compare commits

..

1 Commits

Author SHA1 Message Date
Martin Hauser
acc7c4af9d feat(extras): Add AVIF support for image attachments
Extends allowed image file formats to include AVIF for better modern
format support. Updates form widgets to explicitly support AVIF in
Firefox with the `accept` attribute.

Fixes #21039
2026-01-15 21:21:25 +01:00
3 changed files with 13 additions and 13 deletions

View File

@@ -22,7 +22,7 @@ from utilities.forms.fields import (
DynamicModelMultipleChoiceField, JSONField, SlugField,
)
from utilities.forms.rendering import FieldSet, ObjectAttribute
from utilities.forms.widgets import ChoicesWidget, HTMXSelect
from utilities.forms.widgets import ChoicesWidget, ClearableFileInput, HTMXSelect
from utilities.tables import get_table_for_model
from virtualization.models import Cluster, ClusterGroup, ClusterType
@@ -784,6 +784,10 @@ class ImageAttachmentForm(forms.ModelForm):
fields = [
'image', 'name', 'description',
]
# Explicitly set 'image/avif' to support AVIF selection in Firefox
widgets = {
'image': ClearableFileInput(attrs={'accept': 'image/*,image/avif'}),
}
help_texts = {
'name': _("If no name is specified, the file name will be used.")
}

View File

@@ -78,7 +78,7 @@ def image_upload(instance, filename):
"""
upload_dir = 'image-attachments'
default_filename = 'unnamed'
allowed_img_extensions = ('bmp', 'gif', 'jpeg', 'jpg', 'png', 'webp')
allowed_img_extensions = ('avif', 'bmp', 'gif', 'jpeg', 'jpg', 'png', 'webp')
# Normalize Windows paths and create a Path object.
normalized_filename = str(filename).replace('\\', '/')

View File

@@ -188,11 +188,13 @@ class FilterModifierMixin:
key = f'{model._meta.app_label}.{model._meta.model_name}'
filterset_class = registry['filtersets'].get(key)
filterset = filterset_class() if filterset_class else None
for field_name, field in self.fields.items():
lookups = self._get_lookup_choices(field)
if filterset_class:
lookups = self._verify_lookups_with_filterset(field_name, lookups, filterset_class)
if filterset:
lookups = self._verify_lookups_with_filterset(field_name, lookups, filterset)
if len(lookups) > 1:
field.widget = FilterModifierWidget(
@@ -211,14 +213,8 @@ class FilterModifierMixin:
return []
def _verify_lookups_with_filterset(self, field_name, lookups, filterset_class):
"""Verify which lookups are actually supported by the FilterSet.
Args:
field_name: The name of the form field
lookups: List of (lookup_code, lookup_label) tuples to verify
filterset_class: The FilterSet class (not instance) to check against
"""
def _verify_lookups_with_filterset(self, field_name, lookups, filterset):
"""Verify which lookups are actually supported by the FilterSet."""
verified_lookups = []
for lookup_code, lookup_label in lookups:
@@ -227,7 +223,7 @@ class FilterModifierMixin:
else:
filter_key = f'{field_name}__{lookup_code}' if lookup_code != 'exact' else field_name
if filter_key in filterset_class.base_filters:
if filter_key in filterset.filters:
verified_lookups.append((lookup_code, lookup_label))
return verified_lookups