diff --git a/CHANGELOG.md b/CHANGELOG.md
index d698b38..c274ac2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
# Change Log
+## [0.17.1](https://github.com/dldevinc/paper-streamfield/tree/v0.17.1) - 2023-11-07
+
+### Features
+
+- Added the `srcset` field for image resources.
+- Removed the automatic selection of the "[All]" option in the dialogs for
+ the `recreate_variations` and `remove_variations` management commands.
+
+### Bug Fixes
+
+- Fixed a bug where the number of selected items in a collection was not properly
+ included in the deletion confirmation message.
+
## [0.17.0](https://github.com/dldevinc/paper-streamfield/tree/v0.17.0) - 2023-10-08
### ⚠ BREAKING CHANGES
diff --git a/README.md b/README.md
index 5ba8169..92dd94c 100644
--- a/README.md
+++ b/README.md
@@ -144,7 +144,7 @@ class Page(models.Model):
В следующих таблицах перечислены общие поля и свойства обеих моделей:
| Поле | Описание |
-| ------------- | -------------------------------------------------------------------------------------- |
+|---------------|----------------------------------------------------------------------------------------|
| resource_name | Имя файла без пути, суффикса и расширения.
Пример: `report2020`. |
| extension | Расширение файла в нижнем регистре без точки.
Пример: `pdf`. |
| size | Размер файла в байтах. |
@@ -153,30 +153,31 @@ class Page(models.Model):
| created_at | Дата и время создания экземпляра модели. |
| modified_at | Дата и время изменения экземпляра модели. |
-| Свойство | Описание |
-| -------- | ------------------------------------------------------------------------------------------ |
-| name | Полное имя файла.
Пример: `files/report2020_19sc2Kj.pdf`. |
-| url | URL-адрес файла.
Пример: `/media/files/report2020_19sc2Kj.pdf`. |
-| path | Абсолютный путь к файлу.
Пример: `/home/www/django/media/files/report2020_19sc2Kj.pdf`. |
+| Свойство | Описание |
+|----------|---------------------------------------------------------------------------------------------|
+| name | Полное имя файла.
Пример: `files/report2020_19sc2Kj.pdf`. |
+| url | URL-адрес файла.
Пример: `/media/files/report2020_19sc2Kj.pdf`. |
+| path | Абсолютный путь к файлу.
Пример: `/home/www/django/media/files/report2020_19sc2Kj.pdf`. |
Ниже перечислены поля и свойства, специфичные для каждой модели.
Специфичные поля `UploadedFile`:
| Поле | Описание |
-| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
+|--------------|-------------------------------------------------------------------------------------------------------------------------------------------|
| display_name | Удобочитаемое название файла для вывода на сайте.
Заполняется в диалоговом окне редактирования файла.
Пример: `Annual report 2020`. |
Специфичные поля `UploadedImage`:
| Поле | Описание |
-| ----------- | ---------------------------------------------------------------------------- |
+|-------------|------------------------------------------------------------------------------|
| title | Название изображения, которое можно вставить в атрибут `title` тэга ``. |
| description | Описание изображения, которое можно вставить в атрибут `alt` тэга ``. |
| width | Ширина загруженного изображения. |
| height | Высота загруженного изображения. |
| ratio | Отношение ширины изображения к высоте в формате `Decimal`. |
| hw_ratio | Отношение высоте изображения к ширине в формате `Decimal`. |
+| srcset | Строка формата `[URL] [WIDTH]w`. |
Большинство полей заполняются автоматически при загрузке файла и предназначены
только для чтения. Но такие поля, как `display_name` или `title`, заполняются
@@ -521,7 +522,7 @@ PAPER_UPLOADS = {
но связанная с ним модель `UploadedSVGFile` включает несколько дополнительных полей:
| Поле | Описание |
-| ----------- | ---------------------------------------------------------------------------- |
+|-------------|------------------------------------------------------------------------------|
| width | Ширина изображения в формате `Decimal`. Может быть вещественным числом. |
| height | Высота изображения в формате `Decimal`. Может быть вещественным числом. |
| title | Название изображения, которое можно вставить в атрибут `title` тэга ``. |
diff --git a/paper_uploads/__init__.py b/paper_uploads/__init__.py
index 1948e91..6facdd5 100644
--- a/paper_uploads/__init__.py
+++ b/paper_uploads/__init__.py
@@ -1,2 +1,2 @@
-__version__ = "0.17.0"
+__version__ = "0.17.1"
default_app_config = "paper_uploads.apps.Config"
diff --git a/paper_uploads/files.py b/paper_uploads/files.py
index b096f35..bf09e0c 100644
--- a/paper_uploads/files.py
+++ b/paper_uploads/files.py
@@ -152,6 +152,13 @@ def hw_ratio(self) -> Decimal:
round(operator.truediv(*reversed(self._get_image_dimensions())), 8)
))
+ @property
+ def srcset(self) -> str:
+ return "{} {}w".format(
+ self.url,
+ self.width
+ )
+
@cached_method("_dimensions_cache")
def _get_image_dimensions(self):
return self.variation.get_output_size(
diff --git a/paper_uploads/management/commands/recreate_variations.py b/paper_uploads/management/commands/recreate_variations.py
index a6c693f..d1e56e6 100644
--- a/paper_uploads/management/commands/recreate_variations.py
+++ b/paper_uploads/management/commands/recreate_variations.py
@@ -174,8 +174,7 @@ def get_collection_variations(self):
self._field_name,
multiple=True,
prepend_choices=["[All]"],
- append_choices=["[Back]", "[Exit]"],
- default="[All]"
+ append_choices=["[Back]", "[Exit]"]
)
if "[Exit]" in variations:
@@ -200,8 +199,7 @@ def get_resource_variations(self):
self._field_name,
multiple=True,
prepend_choices=["[All]"],
- append_choices=["[Back]", "[Exit]"],
- default="[All]"
+ append_choices=["[Back]", "[Exit]"]
)
if "[Exit]" in variations:
diff --git a/paper_uploads/management/commands/remove_variations.py b/paper_uploads/management/commands/remove_variations.py
index 2a59cae..0367004 100644
--- a/paper_uploads/management/commands/remove_variations.py
+++ b/paper_uploads/management/commands/remove_variations.py
@@ -169,8 +169,7 @@ def get_collection_variations(self):
self._field_name,
multiple=True,
prepend_choices=["[All]"],
- append_choices=["[Back]", "[Exit]"],
- default="[All]"
+ append_choices=["[Back]", "[Exit]"]
)
if "[Exit]" in variations:
@@ -195,8 +194,7 @@ def get_resource_variations(self):
self._field_name,
multiple=True,
prepend_choices=["[All]"],
- append_choices=["[Back]", "[Exit]"],
- default="[All]"
+ append_choices=["[Back]", "[Exit]"]
)
if "[Exit]" in variations:
diff --git a/paper_uploads/models/base.py b/paper_uploads/models/base.py
index 5356bd7..da728e1 100644
--- a/paper_uploads/models/base.py
+++ b/paper_uploads/models/base.py
@@ -687,6 +687,13 @@ def hw_ratio(self) -> Decimal:
"""
return Decimal(str(round(self.height / self.width, 8)))
+ @property
+ def srcset(self) -> str:
+ return "{} {}w".format(
+ self.url,
+ round(self.width)
+ )
+
def as_dict(self) -> Dict[str, Any]:
return {
**super().as_dict(), # noqa
@@ -788,6 +795,13 @@ def hw_ratio(self) -> Decimal:
"""
return Decimal(str(round(self.height / self.width, 8)))
+ @property
+ def srcset(self) -> str:
+ return "{} {}w".format(
+ self.url,
+ self.width
+ )
+
def as_dict(self) -> Dict[str, Any]:
return {
**super().as_dict(), # noqa
diff --git a/paper_uploads/static/paper_uploads/src/js/widgets/collection.js b/paper_uploads/static/paper_uploads/src/js/widgets/collection.js
index 2ac6cc6..329ee16 100644
--- a/paper_uploads/static/paper_uploads/src/js/widgets/collection.js
+++ b/paper_uploads/static/paper_uploads/src/js/widgets/collection.js
@@ -1142,7 +1142,8 @@ class Collection extends EventEmitter {
),
{
count: selectedItems.length
- }
+ },
+ true
),
buttons: [
{
diff --git a/tests/tests/models/test_dummy.py b/tests/tests/models/test_dummy.py
index a077612..6fddae9 100644
--- a/tests/tests/models/test_dummy.py
+++ b/tests/tests/models/test_dummy.py
@@ -952,6 +952,12 @@ def test_ratio(self, storage):
def test_hw_ratio(self, storage):
assert storage.resource.hw_ratio == Decimal("0.72122251")
+ def test_srcset(self, storage):
+ assert utils.match_path(
+ storage.resource.srcset,
+ "/media/{} 3501w".format(self.resource_name),
+ )
+
def test_prepare_file(self, storage):
obj = DummyImageFieldResource()
with open(CALLIPHORA_FILEPATH, "rb") as fp:
@@ -1079,6 +1085,12 @@ def test_ratio(self, storage):
def test_hw_ratio(self, storage):
assert storage.resource.hw_ratio == Decimal("0.734375")
+ def test_srcset(self, storage):
+ assert utils.match_path(
+ storage.resource.srcset,
+ "/media/{} 1024w".format(self.resource_name),
+ )
+
def test_as_dict(self, storage):
utils.compare_dicts(
storage.resource.as_dict(),
diff --git a/tests/tests/models/test_image.py b/tests/tests/models/test_image.py
index c0b9c33..9473de3 100644
--- a/tests/tests/models/test_image.py
+++ b/tests/tests/models/test_image.py
@@ -66,6 +66,12 @@ def test_ratio(self, storage):
def test_hw_ratio(self, storage):
assert storage.resource.hw_ratio == Decimal("1.49004975")
+ def test_srcset(self, storage):
+ assert utils.match_path(
+ storage.resource.srcset,
+ "/media/{} 804w".format(self.resource_name),
+ )
+
def test_calculate_max_size(self, storage):
assert storage.resource.calculate_max_size((3000, 2000)) == (1800, 1200)
assert storage.resource.calculate_max_size((2000, 3000)) == (800, 1200)
diff --git a/tests/tests/models/test_svg.py b/tests/tests/models/test_svg.py
index a6ea780..6f65221 100644
--- a/tests/tests/models/test_svg.py
+++ b/tests/tests/models/test_svg.py
@@ -61,6 +61,12 @@ def test_ratio(self, storage):
def test_hw_ratio(self, storage):
assert storage.resource.hw_ratio == Decimal("1.05439808")
+ def test_srcset(self, storage):
+ assert utils.match_path(
+ storage.resource.srcset,
+ "/media/{} 626w".format(self.resource_name),
+ )
+
def test_as_dict(self, storage):
utils.compare_dicts(
storage.resource.as_dict(),
diff --git a/tests/tests/test_files.py b/tests/tests/test_files.py
index a6b44b3..44c6f4e 100644
--- a/tests/tests/test_files.py
+++ b/tests/tests/test_files.py
@@ -81,6 +81,12 @@ def test_ratio(self, storage):
def test_hw_ratio(self, storage):
assert storage.file.hw_ratio == Decimal("0.72125")
+ def test_srcset(self, storage):
+ assert utils.match_path(
+ storage.file.srcset,
+ "/media/{}/milky-way-nasa{{suffix}}.desktop.jpg 800w".format(self.resource_folder),
+ )
+
def test_read(self, storage):
assert storage.file.closed is True
with storage.file.open():