Skip to content

Commit 09f75f7

Browse files
authored
Merge branch 'master' into fix/user-model-searchfield
2 parents 21a386b + c610365 commit 09f75f7

File tree

11 files changed

+209
-33
lines changed

11 files changed

+209
-33
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ repos:
2121
# args: [--target-version, "2.2"]
2222

2323
- repo: https://github.com/PyCQA/flake8
24-
rev: 7.1.1
24+
rev: 7.1.2
2525
hooks:
2626
- id: flake8
2727

CHANGELOG.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,25 @@
22
CHANGELOG
33
=========
44

5+
3.3.1 (2024-12-07)
6+
==================
7+
8+
* fix: editing buttons missing in admin when file present by @pajowu in https://github.com/django-cms/django-filer/pull/1511
9+
* fix: incompatibility with djangocms-versioning-filer 1.3 was fixed by @fscherf in https://github.com/django-cms/django-filer/pull/1509
10+
11+
**New Contributors**
12+
13+
* @pajowu made their first contribution in https://github.com/django-cms/django-filer/pull/1511
14+
* @fscherf made their first contribution in https://github.com/django-cms/django-filer/pull/1509
15+
16+
3.3.0 (2024-11-19)
17+
==================
18+
19+
* fix: Restrict upload of binary or unknown file types by default by @fsbraun in https://github.com/django-cms/django-filer/pull/1507
20+
* fix: remove extra brace in generated HTML of data-max-filesize attribute by @fabien-michel in https://github.com/django-cms/django-filer/pull/1502
21+
* fix: uploadButton data-max-filesize attribute is not passed to file-uploader by @fabien-michel in https://github.com/django-cms/django-filer/pull/1503
22+
* docs: Update for on_delete requirement in Filer fields
23+
524
3.2.3 (2024-09-18)
625
==================
726

README.rst

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -49,26 +49,6 @@ Documentation
4949
Please head over to the separate `documentation <https://django-filer.readthedocs.io/en/latest/index.html>`_
5050
for all the details on how to install, configure and use django-filer.
5151

52-
Upgrading
53-
=========
54-
55-
Version 3.3
56-
-----------
57-
58-
django-filer version 3 contains a change in security policy for file uploads.
59-
**By default, binary file or files of unknown type are not allowed to be uploaded.**
60-
To allow upload of binary files in your project, add
61-
62-
.. code-block:: python
63-
64-
FILER_REMOVE_FILE_VALIDATORS = [
65-
"application/octet-stream",
66-
]
67-
68-
to your project's settings. Be aware that binary files always are a security risk.
69-
See the documentation for more information on how to configure file upload validators,
70-
e.g., running files through a virus checker.
71-
7252

7353
.. |pypi| image:: https://badge.fury.io/py/django-filer.svg
7454
:target: http://badge.fury.io/py/django-filer

docs/upgrading.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,25 @@ Usually upgrade procedure is straightforward: update the package and run migrati
77
require special attention from the developer and here we provide upgrade instructions for such cases.
88

99

10+
from 3.x to 3.3
11+
---------------
12+
13+
django-filer version 3.3 contains a change in security policy for file uploads.
14+
**By default, binary file or files of unknown type are not allowed to be uploaded.**
15+
To allow upload of binary files in your project, add
16+
17+
.. code-block:: python
18+
19+
FILER_REMOVE_FILE_VALIDATORS = [
20+
"application/octet-stream",
21+
]
22+
23+
to your project's settings. Be aware that binary files always are a security risk.
24+
See :ref:`check_virus` for more information on how to configure file upload validators,
25+
e.g., running files through a virus checker.
26+
27+
28+
1029
from 2.x to 3.0
1130
---------------
1231

docs/usage.rst

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,11 @@ Simple example ``models.py``::
4242
class Company(models.Model):
4343
name = models.CharField(max_length=255)
4444
logo = FilerImageField(null=True, blank=True,
45-
related_name="logo_company")
45+
related_name="logo_company",
46+
on_delete=models.SET_NULL)
4647
disclaimer = FilerFileField(null=True, blank=True,
47-
related_name="disclaimer_company")
48+
related_name="disclaimer_company",
49+
on_delete=models.SET_NULL)
4850

4951
multiple file fields on the same model::
5052

@@ -53,12 +55,21 @@ multiple file fields on the same model::
5355

5456
class Book(models.Model):
5557
title = models.CharField(max_length=255)
56-
cover = FilerImageField(related_name="book_covers")
57-
back = FilerImageField(related_name="book_backs")
58+
cover = FilerImageField(related_name="book_covers",
59+
on_delete=models.CASCADE)
60+
back = FilerImageField(related_name="book_backs",
61+
on_delete=models.CASCADE)
5862

59-
As with `django.db.models.ForeignKey`_ in general, you have to define a
60-
non-clashing ``related_name`` if there are multiple ``ForeignKey`` s to the
61-
same model.
63+
As with `django.db.models.ForeignKey`_ in general:
64+
65+
* You must specify an ``on_delete`` parameter to define what happens when the referenced file is deleted
66+
* You have to define a non-clashing ``related_name`` if there are multiple ``ForeignKey`` s to the same model
67+
68+
Common ``on_delete`` options:
69+
70+
* ``models.CASCADE`` - Delete the model containing the FilerFileField when the referenced file is deleted
71+
* ``models.SET_NULL`` - Set the reference to NULL when the file is deleted (requires ``null=True``)
72+
* ``models.PROTECT`` - Prevent deletion of the referenced file
6273

6374
templates
6475
.........

docs/validation.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,8 @@ If you distinguish validation by the mime type, remember to register the
264264
validator function for all relevant mime types.
265265

266266

267+
.. _check_virus:
268+
267269
Checking uploads for viruses using ClamAV
268270
-----------------------------------------
269271

filer/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@
1313
8. Publish the release and it will automatically release to pypi
1414
"""
1515

16-
__version__ = '3.2.3'
16+
__version__ = '3.3.1'

filer/admin/fileadmin.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ class Meta:
3535

3636
def __init__(self, *args, **kwargs):
3737
super().__init__(*args, **kwargs)
38-
self.fields["file"].widget = forms.FileInput()
38+
if "file" in self.fields:
39+
self.fields["file"].widget = forms.FileInput()
3940

4041
def clean(self):
4142
from ..validation import validate_upload

filer/templates/admin/filer/widgets/admin_file.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<span class="filerFile js-file-selector">
2727
{% if object %}
2828
{% if object.file.exists %}
29-
<a href="{{ object.url }}" target="_blank">{% file_icon object detail="table" %}</a>
29+
<a href="{{ object.url }}" target="_blank">{% file_icon object detail="thumbnail" %}</a>
3030
&nbsp;<span class="description_text">{{ object.label }}</span>
3131
{% else %}
3232
{% file_icon object %}

filer/utils/files.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import mimetypes
22
import os
3+
import uuid
34

45
from django.http.multipartparser import ChunkIter, SkipFile, StopFutureHandlers, StopUpload, exhaust
56
from django.template.defaultfilters import slugify as slugify_django
@@ -121,6 +122,33 @@ def slugify(string):
121122
return slugify_django(force_str(string))
122123

123124

125+
def _ensure_safe_length(filename, max_length=155, random_suffix_length=16):
126+
"""
127+
Ensures that the filename does not exceed the maximum allowed length.
128+
If it does, the function truncates the filename and appends a random hexadecimal
129+
suffix of length `random_suffix_length` to ensure uniqueness and compliance with
130+
database constraints - even after markers for a thumbnail are added.
131+
132+
Parameters:
133+
filename (str): The filename to check.
134+
max_length (int): The maximum allowed length for the filename.
135+
random_suffix_length (int): The length of the random suffix to append.
136+
137+
Returns:
138+
str: The safe filename.
139+
140+
141+
Reference issue: https://github.com/django-cms/django-filer/issues/1270
142+
"""
143+
144+
if len(filename) <= max_length:
145+
return filename
146+
147+
keep_length = max_length - random_suffix_length
148+
random_suffix = uuid.uuid4().hex[:random_suffix_length]
149+
return filename[:keep_length] + random_suffix
150+
151+
124152
def get_valid_filename(s):
125153
"""
126154
like the regular get_valid_filename, but also slugifies away
@@ -131,6 +159,9 @@ def get_valid_filename(s):
131159
filename = slugify(filename)
132160
ext = slugify(ext)
133161
if ext:
134-
return "{}.{}".format(filename, ext)
162+
valid_filename = "{}.{}".format(filename, ext)
135163
else:
136-
return "{}".format(filename)
164+
valid_filename = "{}".format(filename)
165+
166+
# Ensure the filename meets the maximum length requirements.
167+
return _ensure_safe_length(valid_filename)

0 commit comments

Comments
 (0)