From 69c3de400706f11c77516d0349df5a69f0c6488d Mon Sep 17 00:00:00 2001 From: pix666 Date: Tue, 12 Dec 2023 18:37:03 +0400 Subject: [PATCH] improve management commands --- CHANGELOG.md | 10 ++ README.md | 18 ++-- .../commands/recreate_variations.py | 91 ++++++++++++++----- .../management/commands/remove_variations.py | 91 ++++++++++++++----- 4 files changed, 153 insertions(+), 57 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dcecce2..272e4e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,16 @@ - Added support for Python 3.12. - Added support for Django 5.0. +### Features + +- The `--field` parameter in the `recreate_variations` and `remove_variations` + management commands is an alias for the `--item-type` parameter. +- Now, parameters for the `recreate_variations` and `remove_variations` management + commands can be positional. Example: + ```bash + python3 recreate_variations app.Page background desktop mobile + ``` + ### Bug Fixes - The behavior of `Ctrl+Z` has been fixed when executing management commands. diff --git a/README.md b/README.md index a5e047d..c3a7c3d 100644 --- a/README.md +++ b/README.md @@ -866,19 +866,19 @@ python3 manage.py create_missing_variations ```shell # for collections -python3 manage.py recreate_variations --model app.Photos --item-type image +python3 manage.py recreate_variations app.Photos image # for regular models -python3 manage.py recreate_variations --model app.Page --field image +python3 manage.py recreate_variations app.Page image ``` -По умолчанию перенарезаются все возможные вариации для каждого -экземпляра указанной модели. Можно указать конкретные вариации, -которые нужно перенарезать: +В результате вызова этих команд, пользователю будет предложено выбрать +вариации, которые следует обновить. + +Можно сразу указать нужные вариации: ```shell -python3 manage.py recreate_variations --model app.Page --field image \ - --variations desktop mobile +python3 manage.py recreate_variations app.Page image -- desktop mobile ``` ### remove_variations @@ -889,10 +889,10 @@ python3 manage.py recreate_variations --model app.Page --field image \ ```shell # for collections -python3 manage.py remove_variations --model app.Photos --item-type image +python3 manage.py remove_variations app.Photos image # for regular models -python3 manage.py remove_variations --model app.Page --field image +python3 manage.py remove_variations app.Page image ``` ## Settings diff --git a/paper_uploads/management/commands/recreate_variations.py b/paper_uploads/management/commands/recreate_variations.py index 6d718cd..3261af3 100644 --- a/paper_uploads/management/commands/recreate_variations.py +++ b/paper_uploads/management/commands/recreate_variations.py @@ -2,6 +2,7 @@ from enum import Enum, auto from django.apps import apps +from django.core.exceptions import FieldDoesNotExist from django.core.management import BaseCommand from django.db import DEFAULT_DB_ALIAS @@ -31,8 +32,9 @@ class Command(BaseCommand): python3 manage.py recreate_variations blog.post --field=hero Пример для коллекции: - python3 manage.py recreate_variations blog.gallery --item-type=image + python3 manage.py recreate_variations blog.gallery --field=image """ + args = None options = None verbosity = None database = DEFAULT_DB_ALIAS @@ -45,8 +47,13 @@ class Command(BaseCommand): _variation_names = None def add_arguments(self, parser): + parser.add_argument( + "args", + nargs="*" + ) parser.add_argument( "--model", + nargs="?", metavar="[APP_LABEL].[MODEL_NAME]", help="Specifies the model to recreate variations for", ) @@ -82,6 +89,7 @@ def add_arguments(self, parser): ) def handle(self, *args, **options): + self.args = args self.options = options self.verbosity = options["verbosity"] self.database = options["database"] @@ -115,21 +123,27 @@ def loop(self): def get_model(self): model_name = self.options["model"] + if model_name is None and self.args: + model_name = self.args[0] + if model_name is None: model_name = helpers.select_resource_model( append_choices=["[Exit]"], predicate=lambda model: utils.includes_variations(model), ) - if model_name is None or model_name == "[Exit]": - raise ExitException + if model_name is None or model_name == "[Exit]": + raise ExitException self._model = apps.get_model(model_name) self._is_collection = utils.is_collection(self._model) self._step = Step.GET_FIELD def get_collection_field(self): - item_type = self.options["item_type"] + item_type = self.options["item_type"] or self.options["field"] + if item_type is None and len(self.args) >= 2: + item_type = self.args[1] + if item_type is None: item_type = helpers.select_collection_item_type( self._model, @@ -137,18 +151,28 @@ def get_collection_field(self): append_choices=["[Back]", "[Exit]"] ) - if item_type is None or item_type == "[Exit]": - raise ExitException + if item_type is None or item_type == "[Exit]": + raise ExitException - if item_type == "[Back]": - self._step = Step.GET_MODEL - return + if item_type == "[Back]": + self._step = Step.GET_MODEL + return + + # Check the field exists + if item_type not in self._model.item_types: + raise FieldDoesNotExist("{} has no field named '{}'".format( + self._model.__name__, + item_type + )) self._field_name = item_type self._step = Step.GET_VARIATIONS def get_resource_field(self): field_name = self.options["field"] + if field_name is None and len(self.args) >= 2: + field_name = self.args[1] + if field_name is None: field_name = helpers.select_resource_field( self._model, @@ -156,18 +180,29 @@ def get_resource_field(self): append_choices=["[Back]", "[Exit]"] ) - if field_name is None or field_name == "[Exit]": - raise ExitException + if field_name is None or field_name == "[Exit]": + raise ExitException - if field_name == "[Back]": - self._step = Step.GET_MODEL - return + if field_name == "[Back]": + self._step = Step.GET_MODEL + return + + # Check the field exists + self._model._meta.get_field(field_name) self._field_name = field_name self._step = Step.GET_VARIATIONS def get_collection_variations(self): variations = self.options["variations"] + if variations is None and len(self.args) >= 3: + variations = set( + name.strip() + for arg in self.args[2:] + for name in arg.split(",") + if name.strip() + ) + if variations is None: variations = helpers.select_collection_variations( self._model, @@ -177,12 +212,12 @@ def get_collection_variations(self): append_choices=["[Back]", "[Exit]"] ) - if variations is None or "[Exit]" in variations: - raise ExitException + if variations is None or "[Exit]" in variations: + raise ExitException - if "[Back]" in variations: - self._step = Step.GET_FIELD - return + if "[Back]" in variations: + self._step = Step.GET_FIELD + return if "[All]" in variations: self._variation_names = ALL_VARIATIONS @@ -193,6 +228,14 @@ def get_collection_variations(self): def get_resource_variations(self): variations = self.options["variations"] + if variations is None and len(self.args) >= 3: + variations = set( + name.strip() + for arg in self.args[2:] + for name in arg.split(",") + if name.strip() + ) + if variations is None: variations = helpers.select_resource_variations( self._model, @@ -202,12 +245,12 @@ def get_resource_variations(self): append_choices=["[Back]", "[Exit]"] ) - if variations is None or "[Exit]" in variations: - raise ExitException + if variations is None or "[Exit]" in variations: + raise ExitException - if "[Back]" in variations: - self._step = Step.GET_FIELD - return + if "[Back]" in variations: + self._step = Step.GET_FIELD + return if "[All]" in variations: self._variation_names = ALL_VARIATIONS diff --git a/paper_uploads/management/commands/remove_variations.py b/paper_uploads/management/commands/remove_variations.py index 756b251..7e072ca 100644 --- a/paper_uploads/management/commands/remove_variations.py +++ b/paper_uploads/management/commands/remove_variations.py @@ -2,6 +2,7 @@ from enum import Enum, auto from django.apps import apps +from django.core.exceptions import FieldDoesNotExist from django.core.management import BaseCommand from django.db import DEFAULT_DB_ALIAS @@ -31,8 +32,9 @@ class Command(BaseCommand): python3 manage.py remove_variations blog.post --field=hero Пример для коллекции: - python3 manage.py remove_variations blog.gallery --item-type=image + python3 manage.py remove_variations blog.gallery --field=image """ + args = None options = None verbosity = None database = DEFAULT_DB_ALIAS @@ -45,8 +47,13 @@ class Command(BaseCommand): _variation_names = None def add_arguments(self, parser): + parser.add_argument( + "args", + nargs="*" + ) parser.add_argument( "--model", + nargs="?", metavar="[APP_LABEL].[MODEL_NAME]", help="Specifies the model to remove variation files for", ) @@ -77,6 +84,7 @@ def add_arguments(self, parser): ) def handle(self, *args, **options): + self.args = args self.options = options self.verbosity = options["verbosity"] self.database = options["database"] @@ -110,21 +118,27 @@ def loop(self): def get_model(self): model_name = self.options["model"] + if model_name is None and self.args: + model_name = self.args[0] + if model_name is None: model_name = helpers.select_resource_model( append_choices=["[Exit]"], predicate=lambda model: utils.includes_variations(model), ) - if model_name is None or model_name == "[Exit]": - raise ExitException + if model_name is None or model_name == "[Exit]": + raise ExitException self._model = apps.get_model(model_name) self._is_collection = utils.is_collection(self._model) self._step = Step.GET_FIELD def get_collection_field(self): - item_type = self.options["item_type"] + item_type = self.options["item_type"] or self.options["field"] + if item_type is None and len(self.args) >= 2: + item_type = self.args[1] + if item_type is None: item_type = helpers.select_collection_item_type( self._model, @@ -132,18 +146,28 @@ def get_collection_field(self): append_choices=["[Back]", "[Exit]"] ) - if item_type is None or item_type == "[Exit]": - raise ExitException + if item_type is None or item_type == "[Exit]": + raise ExitException - if item_type == "[Back]": - self._step = Step.GET_MODEL - return + if item_type == "[Back]": + self._step = Step.GET_MODEL + return + + # Check the field exists + if item_type not in self._model.item_types: + raise FieldDoesNotExist("{} has no field named '{}'".format( + self._model.__name__, + item_type + )) self._field_name = item_type self._step = Step.GET_VARIATIONS def get_resource_field(self): field_name = self.options["field"] + if field_name is None and len(self.args) >= 2: + field_name = self.args[1] + if field_name is None: field_name = helpers.select_resource_field( self._model, @@ -151,18 +175,29 @@ def get_resource_field(self): append_choices=["[Back]", "[Exit]"] ) - if field_name is None or field_name == "[Exit]": - raise ExitException + if field_name is None or field_name == "[Exit]": + raise ExitException - if field_name == "[Back]": - self._step = Step.GET_MODEL - return + if field_name == "[Back]": + self._step = Step.GET_MODEL + return + + # Check the field exists + self._model._meta.get_field(field_name) self._field_name = field_name self._step = Step.GET_VARIATIONS def get_collection_variations(self): variations = self.options["variations"] + if variations is None and len(self.args) >= 3: + variations = set( + name.strip() + for arg in self.args[2:] + for name in arg.split(",") + if name.strip() + ) + if variations is None: variations = helpers.select_collection_variations( self._model, @@ -172,12 +207,12 @@ def get_collection_variations(self): append_choices=["[Back]", "[Exit]"] ) - if variations is None or "[Exit]" in variations: - raise ExitException + if variations is None or "[Exit]" in variations: + raise ExitException - if "[Back]" in variations: - self._step = Step.GET_FIELD - return + if "[Back]" in variations: + self._step = Step.GET_FIELD + return if "[All]" in variations: self._variation_names = ALL_VARIATIONS @@ -188,6 +223,14 @@ def get_collection_variations(self): def get_resource_variations(self): variations = self.options["variations"] + if variations is None and len(self.args) >= 3: + variations = set( + name.strip() + for arg in self.args[2:] + for name in arg.split(",") + if name.strip() + ) + if variations is None: variations = helpers.select_resource_variations( self._model, @@ -197,12 +240,12 @@ def get_resource_variations(self): append_choices=["[Back]", "[Exit]"] ) - if variations is None or "[Exit]" in variations: - raise ExitException + if variations is None or "[Exit]" in variations: + raise ExitException - if "[Back]" in variations: - self._step = Step.GET_FIELD - return + if "[Back]" in variations: + self._step = Step.GET_FIELD + return if "[All]" in variations: self._variation_names = ALL_VARIATIONS