Руководство по серверному API

Фреймворк VST Utils использует Django, Django Rest Framework, drf-yasg и Celery.

Модели

Модель - это единственный и окончательный источник истины о ваших данных. Она содержит основные поля и поведение для данных, которые вы храните. Хорошей практикой считается избегать написания собственных view и сериализаторов, поскольку BModel предоставляет богатый набор мета-атрибутов для их автоматической генерации в большинстве ситуаций.

Переопределение стандартных классов моделей Django в модуле vstutils.models.

class vstutils.models.BModel(*args, **kwargs)[исходный код]

Стандартный класс модели, генерирующий viewset, отдельные сериализаторы для list() и retrieve(), фильтры, api endpoint-ы и вложенные view.

Примеры:
from django.db import models
from rest_framework.fields import ChoiceField
from vstutils.models import BModel

class Stage(BModel):
    name = models.CharField(max_length=256)
    order = models.IntegerField(default=0)

    class Meta:
        default_related_name = "stage"
        ordering = ('order', 'id',)
        # fields which would be showed on list.
        _list_fields = [
            'id',
            'name',
        ]
        # fields which would be showed on detail view and creation.
        _detail_fields = [
            'id',
            'name',
            'order'
        ]
        # make order as choices from 0 to 9
        _override_detail_fields = {
            'order': ChoiceField((str(i) for i in range(10)))
        }


class Task(BModel):
    name = models.CharField(max_length=256)
    stages = models.ManyToManyField(Stage)
    _translate_model = 'Task'

    class Meta:
        # fields which would be showed.
        _list_fields = [
            'id',
            'name',
        ]
        # create nested views from models
        _nested = {
            'stage': {
                'allow_append': False,
                'model': Stage
            }
        }

В данном случае создаются модели, которые затем будут конвертированы во view, где:

  • POST/GET на /api/version/task/ - создает новую задачу или получает список всех задач

  • PUT/PATCH/GET/DELETE на /api/version/task/:id/ - обновляет, получает или удаляет экземпляр задачи

  • POST/GET to /api/version/task/:id/stage/ - создает новую стадию или получает список всех стадий в задаче

  • PUT/PATCH/GET/DELETE на /api/version/task/:id/stage/:stage_id - обновляет, получает или удаляет экземпляр стадии в задаче.

Чтобы добавить view к API, вставьте следующий код в settings.py:

API[VST_API_VERSION][r'task'] = {
    'model': 'your_application.models.Task'
}

Для первичного доступа к сгенерированному view, наследуйтесь от свойства Task.generated_view.

Чтобы упростить процесс перевода на фронтенде, используйте атрибут _translate_model вместе с названием модели.

Список мета-атрибутов для генерации view:

  • _view_class - список дополнительных классов view для наследования. Класс, унаследованный от ViewSet или строка для его импорта. Константы также поддерживаются:

    • read_only - для создания view, поддерживающего только просмотр;

    • list_only - для создания view, поддерживающего только список;

    • history - для создания view, поддерживающего только просмотр и удаление записей.

    Представление, поддерживающее все CRUD-операции, применяется по умолчанию.

  • _serializer_class - класс API сериализатора; используйте этот атрибут, чтобы указать родительский класс автоматически сгенерированных сериализаторов. По умолчанию используется vstutils.api.serializers.VSTSerializer. Принимает строку для импорта, класс сериализатора или django.utils.functional.SimpleLazyObject.

  • _serializer_class_name - название модели для OpenAPI definitions. Это название будет в сгенерированном интерфейсе администратора. По умолчанию используется имя класса.

  • _list_fields или _detail_fields - список полей, которые будут отображены в списке или детальной записи соответственно. То же, что и мета-атрибут «fields» в сериализаторах DRF.

  • _override_list_fields или _override_detail_fields - сопоставление имен и типов полей, которые будут переопределены в атрибутах сериализатора (думайте об этом как о переопределении полей в ModelSerializer из DRF).

  • _properties_groups - словарь, где ключами являются названия групп, а значениями - списки полей (строки). Позволяет группировать поля в секции на фронтенде.

  • _view_field_name - поле, которое будет использовано для вывода заголовка детальной записи.

  • _non_bulk_methods - список методов, которые не должны использовать bulk для запросов.

  • _extra_serializer_classes - сопоставление с дополнительными сериализаторами во viewset. Это может быть, например, сериализатор, который будет вычислять что-то в действии (имя сопоставления). Значением может быть строка для импорта. Важное замечание: при установке атрибута model в значение None будет использован стандартный механизм генерации сериализаторов, что позволит получить поля из list или detail сериализаторов (установите мета-атрибут сериализатора __inject_from__ в list или detail соответственно). В некоторых случаях необходимо передать модель в сериализатор. Для этих целей используйте константу LAZY_MODEL в качестве мета-атрибута. Каждый раз, когда сериализатор будет использован, конкретная модель, в которой он объявлен, будет подставлена.

  • _filterset_fields - список или словарь имен filterset для API-фильтрации. По умолчанию используется список полей list-view. При обработке списка полей проверяет наличие специальных имен полей и наследует дополнительные родительские классы. Если в списке есть id, класс будет наследован от vstutils.api.filters.DefaultIDFilter. Если есть name - от vstutils.api.filters.DefaultNameFilter. Если есть и id, и name, то класс будет наследован от обоих. Возможные значения включают list полей, которые нужно фильтровать, или dict, где ключ - имя поля, а значение - класс Filter. Использование словаря расширяет функциональность атрибута и дает возможность переопределить класс фильтра для отдельных полей (значение None выключает переопределение).

  • _search_fields - кортеж или список полей, которые должны использоваться в поисковых запросах. По умолчанию (или если установлено None) - все фильтруемые поля в detail view.

  • _copy_attrs - список полей экземпляра модели, указывающий, что экземпляр может быть скопирован с этими атрибутами.

  • _nested - сопоставление ключ-значение вложенных view (ключ - имя вложенного view, kwargs для декоратора vstutils.api.decorators.nested_view, но поддерживает атрибут model в качестве вложенного). model может быть строкой для импорта.

  • _extra_view_attributes - сопоставление ключ-значение дополнительных атрибутов view, имеет меньший приоритет перед сгенерированными атрибутами.

Как правило, вы также можете добавить другие атрибуты для переопределения или расширения списка классов обработки по умолчанию. Поддерживаются filter_backends, permission_classes, authentication_classes, throttle_classes, renderer_classes и parser_classes. Список мета-атрибутов для настройки выглядит так:

  • _pre_{attribute} - Список классов, включаемых до классов по умолчанию.

  • _{attribute} - Список классов, включаемых после классов по умолчанию.

  • _override_{attribute} - булев флаг, указывающий, что атрибут переопределяет стандартный viewset (в противном случае расширяет). По умолчанию: False.

Примечание

Возможно, вам потребуется создать экшен в сгенерированном view. Используйте декоратор vstutils.models.decorators.register_view_action с аргументом detail, чтобы применить его к списку или детальной записи. В этом случае декорированный метод будет принимать экземпляр view в self.

Примечание

В некоторых случаях, наследование модели может также требовать наследования класса Meta базовой модели. Если Meta явно объявлен в базовом классе, то вы можете получить его с помощью атрибута OriginalMeta и использовать его для наследования.

Примечание

Строка документации модели будет переиспользована для описания view. Есть возможность сделать общее описание для всех экшенов и описание для каждого отдельно, используя следующий синтаксис:

General description for all actions.

action_name:
    Description for this action.

another_action:
    Description for another action.
hidden

Если hidden установлено в True, вхождение будет исключено из запроса в BQuerySet.

id

Первичное поле для выборки и поиска в API.

class vstutils.models.Manager(*args, **kwargs)[исходный код]

Стандартный VSTUtils-менеджер. Используется классами BaseModel и BModel. Использует BQuerySet в качестве базового.

class vstutils.models.queryset.BQuerySet(model=None, query=None, using=None, hints=None)[исходный код]

Представляет ленивый поиск в базе данных множества объектов. Позволяет перегрузить итерируемый класс по умолчанию с помощью атрибута custom_iterable_class (класс с методом __iter__, возвращающий генератор объектов модели) и стандартный класс запроса с помощью атрибута custom_query_class (дочерний класс django.db.models.sql.query.Query).

cleared()[исходный код]

Фильтрует queryset для моделей с атрибутом hidden, исключая все скрытые объекты.

get_paginator(*args, **kwargs)[исходный код]

Возвращает инициализированные объекты класса vstutils.utils.Paginator через текущий экземпляр QuerySet. Все аргументы и (args) и именованные аргументы (kwargs) попадают в конструктор класса Paginator.

paged(*args, **kwargs)[исходный код]

Возвращает разбитые на страницы данные при помощи пользовательского класса Paginator. Используйте PAGE_LIMIT из глобальных настроек по умолчанию.

class vstutils.models.decorators.register_view_action(*args, **kwargs)[исходный код]

Декоратор, позволяющий обратить методы модели в сгенерированные экшены view. Декорированный метод становится методом сгенерированного view, где self - объект view. Смотрите поддерживаемые аргументы в vstutils.api.decorators.subaction().

Примечание

Возможно вам потребуется использовать прокси-модели со стандартным набором экшенов. Чтобы получить экшен прокси-модели, передайте именованный аргумент inherit со значением True.

Примечание

Часто экшен не должен передавать никаких параметров, отправляя вместо этого пустой запрос. Чтобы ускорить разработку, мы установили сериализатор vstutils.api.serializers.EmptySerializer. по умолчанию.

Вы также можете использовать модели, не нуждающиеся в базе данных:

class vstutils.models.custom_model.ExternalCustomModel(*args, **kwargs)[исходный код]

Данная кастомная модель предназначена для самостоятельной реализации запросов к внешним сервисам. Модель позволяет вам передавать параметры фильтрации, лимитирования и сортировки к внешним запросам, получая уже ограниченные данные.

Чтобы начать использовать эту модель, достаточно реализовать метод класса get_data_generator(), который получает объект запроса с необходимыми параметрами, как аргумент.

class vstutils.models.custom_model.FileModel(*args, **kwargs)[исходный код]

Модель, загружающая данные из YAML-файла вместо базы данных. Путь до файла хранится в атрибуте FileModel.file_path.

Примеры:

Исходный файл хранится в /etc/authors.yaml вместе со следующим содержимым:

- name: "Sergey Klyuykov"
- name: "Michael Taran"

Пример:

from vstutils.custom_model import FileModel, CharField


class Authors(FileModel):
    name = CharField(max_length=512)

    file_path = '/etc/authors.yaml'
class vstutils.models.custom_model.ListModel(*args, **kwargs)[исходный код]

Модель, использующая список или словарь для хранения данных (атрибут ListModel.data) вместо базы данных. Полезна в том случае, если у вас простой набор данных.

Примеры:
from vstutils.custom_model import ListModel, CharField


class Authors(ListModel):
    name = CharField(max_length=512)

    data = [
        {"name": "Sergey Klyuykov"},
        {"name": "Michael Taran"},
    ]

Иногда может быть необходимо переключаться между источниками данных. Для этих целей следует использовать функцию setup_custom_queryset_kwargs, которая принимает именованные аргументы, отправляющиеся затем в функцию инициализации данных. Один из таких аргументов для ListModel - date_source, принимающий любой итерируемый объект.

Примеры:
from vstutils.custom_model import ListModel, CharField


class Authors(ListModel):
    name = CharField(max_length=512)

qs = Authors.objects.setup_custom_queryset_kwargs(data_source=[
    {"name": "Sergey Klyuykov"},
    {"name": "Michael Taran"},
])

В этом случае мы задаем список источников через функцию setup_custom_queryset_kwargs, и каждый последующий вызов в цепочке методов будет работать с этими данными.

data = []

Список кортежей данных. Пустой по умолчанию.

class vstutils.models.custom_model.ViewCustomModel(*args, **kwargs)[исходный код]

Эта модель реализует механизм программирования SQL View над другими моделями. В методе get_view_queryset() подготавливается запрос, и все остальные действия осуществляются поверх него.

Поля Модели

class vstutils.models.fields.FkModelField(to, on_delete, related_name=None, related_query_name=None, limit_choices_to=None, parent_link=False, to_field=None, db_constraint=True, **kwargs)[исходный код]

Расширяет django.db.models.ForeignKey. Используйте это поле в vstutils.models.BModel, чтобы получить vstutils.api.FkModelField в сериализаторе. Чтобы установить Foreign Key отношение, задайте значение to - класс модели или строка для импорта, как в django.db.models.ForeignKey

class vstutils.models.fields.HTMLField(*args, db_collation=None, **kwargs)[исходный код]

Расширяет класс django.db.models.TextField. Простое поле для хранения HTML-разметки. Поле основано на базе django.db.models.TextField, поэтому не поддерживает индексацию и не рекомендовано для использования в фильтрах.

class vstutils.models.fields.MultipleFieldFile(instance, field, name)[исходный код]

Подклассы django.db.models.fields.files.FieldFile. Предоставляют MultipleFieldFile.save() и MultipleFieldFile.delete() для управления базовым файлом, а также для обновления соответствующего экземпляра модели.

delete(save=True)[исходный код]

Удаляет файл из хранилища и из атрибута объекта.

save(name, content, save=True)[исходный код]

Сохраняет изменения в файле в хранилище и атрибут объекта.

class vstutils.models.fields.MultipleFileDescriptor(field)[исходный код]

Подклассы django.db.models.fields.files.FileDescriptor для обработки списка файлов. Возвращает список MultipleFieldFile при обращении, поэтому вы можете написать такой код:

from myapp.models import MyModel
instance = MyModel.objects.get(pk=1)
instance.files[0].size
get_file(file, instance)[исходный код]

Всегда возвращает валидный объект attr_class. За деталями реализации обратитесь к django.db.models.fields.files.FileDescriptor.__get__().

class vstutils.models.fields.MultipleFileField(**kwargs)[исходный код]

Подклассы django.db.models.fields.files.FileField. Поле для хранения списка файлов, содержащихся в хранилище. Все аргументы передаются в FileField.

attr_class

alias of MultipleFieldFile

descriptor_class

alias of MultipleFileDescriptor

class vstutils.models.fields.MultipleFileMixin(**kwargs)[исходный код]

Миксина, предназначенная для использования вместе с django.db.models.fields.files.FieldFile для преобразования его в Field вместе со списком файлов.

get_prep_value(value)[исходный код]

Подготовка значения для вставки в базу данных

pre_save(model_instance, add)[исходный код]

Вызов метода .save() для каждого файла списка

class vstutils.models.fields.MultipleImageField(**kwargs)[исходный код]

Поле для хранения списка изображения, содержащихся в хранилище. Все аргументы передаются в django.db.models.fields.files.ImageField, кроме height_field и width_field, так как они пока не реализованы.

attr_class

alias of MultipleImageFieldFile

descriptor_class

alias of MultipleFileDescriptor

class vstutils.models.fields.MultipleImageFieldFile(instance, field, name)[исходный код]

Подклассы MultipleFieldFile и ImageFile mixin, обрабатывают удаление _dimensions_cache, когда файл удаляется.

class vstutils.models.fields.MultipleNamedBinaryFileInJSONField(*args, db_collation=None, **kwargs)[исходный код]

Расширяет django.db.models.TextField. Используйте это поле в vstutils.models.BModel, чтобы получить vstutils.api.MultipleNamedBinaryFileInJSONField в сериализаторе.

class vstutils.models.fields.MultipleNamedBinaryImageInJSONField(*args, db_collation=None, **kwargs)[исходный код]

Расширяет django.db.models.TextField. Используйте это поле в vstutils.models.BModel, чтобы получить vstutils.api.MultipleNamedBinaryImageInJSONField в сериализаторе.

class vstutils.models.fields.NamedBinaryFileInJSONField(*args, db_collation=None, **kwargs)[исходный код]

Расширяет django.db.models.TextField. Используйте это поле в vstutils.models.BModel, чтобы получить vstutils.api.NamedBinaryFileInJSONField в сериализаторе.

class vstutils.models.fields.NamedBinaryImageInJSONField(*args, db_collation=None, **kwargs)[исходный код]

Расширяет django.db.models.TextField. Используйте это поле в vstutils.models.BModel, чтобы получить vstutils.api.NamedBinaryImageInJSONField в сериализаторе.

class vstutils.models.fields.WYSIWYGField(*args, db_collation=None, **kwargs)[исходный код]

Расширяет django.db.models.TextField. Простое поле для хранения строк в формате Markdown. Поле основано на django.db.models.TextField, поэтому не поддерживает индексацию и не рекомендовано для использования в фильтрах.

Веб-API

Веб-API основано на Django Rest Framework. Предоставляет дополнительные вложенные функции.

Поля

Фреймворк включает в себя список удобных полей сериализатора. Некоторые из них вступают в силу только в сгенерированном интерфейсе администратора.

Дополнительные поля сериализатора для генерации OpenAPI и графического интерфейса.

class vstutils.api.fields.AutoCompletionField(*args, **kwargs)[исходный код]

Поле, предоставляющее автодополнение на фронтенде. Использует указанный список объектов.

Параметры:
  • autocomplete (list,tuple,str) – Источник для автодополнения. Можно задать список/кортеж со значениями или definition name в схеме OpenAPI. Для definition пользовательский интерфейс найдет оптимальную ссылку и отобразит значения, основанные на аргументах autocomplete_property и autocomplete_represent.

  • autocomplete_property (str) – этот аргумент указывает, какие атрибуты будут взяты из model definition схемы OpenAPI в качестве используемого значения.

  • autocomplete_represent – этот аргумент указывает, какие атрибуты будут взяты из model definition схемы OpenAPI в качестве отображаемого значения.

  • use_prefetch (bool) – делает prefetch для значений на фронтенде в list-view. True по умолчанию.

Примечание

Действует только в графическом интерфейсе. Работает аналогично VSTCharField в API.

class vstutils.api.fields.Barcode128Field(*args, **kwargs)[исходный код]

Простое строковое поле. Значение всегда должно быть допустимой строкой ASCII. В пользовательском интерфейсе оно будет отображено как штрихкод (код 128).

Параметры:

child (rest_framework.fields.Field) – поле для сериализации или десериализации оригинальных данных.По умолчанию: rest_framework.fields.CharField

class vstutils.api.fields.BinFileInStringField(*args, **kwargs)[исходный код]

Поле, расширяющее FileInStringField, но работающее также с бинарными (base64) файлами.

Параметры:

media_types (tuple,list) – Список MIME-типов, доступных для выбора пользователем. Поддерживается синтаксис с использованием *. По умолчанию [„*/*“]

Примечание

Действует только в графическом интерфейсе. Работает аналогично VSTCharField в API.

class vstutils.api.fields.CSVFileField(*args, **kwargs)[исходный код]

Поле, расширяющее FileInStringField, используется для работы с csv файлами. Обеспечивает отображение загруженных данных в виде таблицы.

Параметры:
  • items (Serializer) – Конфигурация таблицы. Это сериализатор drf или vst, включающий CharField’ы, которые являются ключами словарей, и именами колонок в таблице. В ключи сериализуются данные из csv. Поля должны быть в том порядке, в котором вы хотите видеть их в таблице. Следующие опции могут также быть включены: - label: удобочитаемое название колонки - required: определяет, будет ли поле обязательным. По умолчанию False.

  • min_column_width (int) – Минимальная ширина ячейки. По умолчанию 200 px.

  • delimiter (str) – Символ-разделитель.

  • lineterminator (str) – Последовательность символов новой строки. Оставьте пустым для выбора автоматически. Возможные значения: \r, \n, \r\n.

  • quotechar (str) – Символ, используемый в качестве кавычек для полей.

  • escapechar (str) – Символ, используемый для экранирования кавычки в поле.

  • media_types (tuple,list) – Список MIME-типов, доступных для выбора пользователем. Поддерживается синтаксис с использованием *. По умолчанию ['text/csv']

class vstutils.api.fields.CommaMultiSelect(*args, **kwargs)[исходный код]

Поле, содержащее список значений с указанным разделителем (по умолчанию «,»). Получает список значений из другой модели или списка. Предоставляет автодополнение, как и AutoCompletionField, но со списками в виде строки, где слова разделяются запятыми. Подходит для полей-свойств модели, где уже реализована основная логика, или для поля model.CharField.

Параметры:
  • select (str,tuple,list) – Определение имени схемы OpenAPI или списка со значениями.

  • select_separator (str) – разделитель значений. По умолчанию запятая.

  • select_property,select_represent – работает так же, как autocomplete_property и autocomplete_represent По умолчанию name.

  • use_prefetch – делает prefetch значений на фронтенде в list-view. По умолчанию False.

  • make_link – Отображает значение как ссылку на модель. По умолчанию True.

  • dependence (dict) – Словарь, где ключи - это имена полей из той же модели, а значения - названия query-фильтров. Если хотя бы одно из полей, от которых существует зависимость не допускает null, обязательно или установлено в null, список автодополнения будет пустым, а поле окажется выключенным.

Примечание

Действует только в графическом интерфейсе. Работает аналогично VSTCharField в API.

class vstutils.api.fields.CrontabField(*args, **kwargs)[исходный код]

Простое поле, аналогичное crontab, содержащее расписание cron-записей для указания времени. Поле crontab имеет пять полей для указания дня, даты и времени. * в поле значений выше означает все допустимые значения, указанные в скобках для данного столбца.

В поле значений может быть * или список элементов, разделенных запятыми. Элементом может быть число из указанных выше диапазонов или два числа из диапазона, разделенных дефисом (означает включительный диапазон).

Поля времени и даты:

Поля

допустимое значение

minute

0-59

hour

0-23

day of month

1-31

month

1-12

day of week

0-7 (0 или 7 - Sunday)

Значение по умолчанию для каждого поля, если не указано, составляет

.---------------- minute (0 - 59)
| .-------------- hour (0 - 23)
| | .------------ day of month (1 - 31)
| | | .---------- month (1 - 12)
| | | | .-------- day of week (0 - 6) (Sunday=0 or 7)
| | | | |
* * * * *
class vstutils.api.fields.DeepFkField(only_last_child=False, parent_field_name='parent', **kwargs)[исходный код]

Расширяет FkModelField, но отображается в виде дерева на фронтенде.

Предупреждение

Это поле не поддерживает dependence. Используйте filters на свой страх и риск, так как они могут сломать структуру дерева.

Параметры:
  • only_last_child (bool) – если True, то допускает к выбору только то значение, которое не имеет дочерних элементов. По умолчанию False

  • parent_field_name (str) – название родительского поля в модели. По умолчанию parent

class vstutils.api.fields.DependEnumField(*args, **kwargs)[исходный код]

Поле, расширяющее DynamicJsonTypeField, но его значение не преобразуется в json, а остается как есть. Полезно при использовании property в модели или для экшенов.

Параметры:
  • field (str) – поле в модели, изменение значения которого будет менять тип текущего значения.

  • types – сопоставление ключ-значение, где ключом является значение поля-подписчика, а значением - тип (формата OpenAPI) текущего поля.

  • choices (dict) – варианты выбора для разных значений подписанных полей. Использует сопоставление, где ключом является подписанное поле, а значением - список значений для выбора.

Примечание

Действует только в графическом интерфейсе. В API работает аналогично VSTCharField без изменения значения.

class vstutils.api.fields.DependFromFkField(*args, **kwargs)[исходный код]

Поле, расширяющее DynamicJsonTypeField. Валидирует данные поля с помощью field_attribute, выбранного в связанной модели. По умолчанию любое значение field_attribute валидируется классом VSTCharField. Чтобы переопределить это поведение, установите словарный атрибут {field_attribute value}_fields_mapping в связанной модели, где:

  • key - строковое представление типа значения, получаемое от связанной модели field_attribute.

  • value - экземпляр rest_framework.Field для валидации.

Параметры:
  • field (str) – поле в модели, чье изменение значения меняет тип текущего значения. Поле должно быть классом FkModelField.

  • field_attribute (str) – атрибут связанного экземпляра модели с именем типа.

Предупреждение

field_attribute в связанной модели должно быть типа rest_framework.fields.ChoicesField, иначе в графическом интерфейсе поле будет отображаться как обычное текстовое.

class vstutils.api.fields.DynamicJsonTypeField(*args, **kwargs)[исходный код]

Поле, тип которого зависит от другого поля. Хранит значение в виде строки, а отображает поле в виде объекта json.

Параметры:
  • field (str) – поле в модели, изменение значения которого будет менять тип текущего значения.

  • types – сопоставление ключ-значение, где ключом является значение поля-подписчика, а значением - тип (формата OpenAPI) текущего поля.

  • choices (dict) – варианты выбора для разных значений подписанных полей. Использует сопоставление, где ключом является подписанное поле, а значением - список значений для выбора.

  • source_view (str) – Позволяет использовать данные родительских view в качестве источника для создания полей. Можно указать точный путь представления (/user/{id}/) или относительный спецификатор родительского представления (<<parent>>.<<parent>>.<<parent>>). Например, если текущая страница - /user/1/role/2/, а source_view - <<parent>>.<<parent>>, то будут использованы данные из /user/1/. Поддерживаются только представления деталей.

Примечание

Действует только в графическом интерфейсе. В API работает аналогично VSTCharField без изменения значения.

class vstutils.api.fields.FileInStringField(*args, **kwargs)[исходный код]

Поле, расширяющее VSTCharField. Сохраняет содержимое файла в виде строки.

Поле должно быть текстовым (не бинарным). Сохраняется в модель как есть.

Параметры:

media_types (tuple,list) – Список MIME-типов, доступных для выбора пользователем. Поддерживается синтаксис с использованием *. По умолчанию ['*/*']

Примечание

Действует только в графическом интерфейсе. В API ведет себя так же, как и VSTCharField.

class vstutils.api.fields.FkField(*args, **kwargs)[исходный код]

Реализация ForeignKeyField. Вы можете указать, какое поле связанной модели будет храниться в этом поле (по умолчанию: «id») и какое будет отображаться на фронтенде.

Параметры:
  • select (str) – Имя определения схемы OpenAPI.

  • autocomplete_property (str) – этот аргумент указывает, какие атрибуты будут взяты из model definition схемы OpenAPI в качестве используемого значения. По умолчанию id.

  • autocomplete_represent – этот аргумент указывает, какие атрибуты будут взяты из model definition схемы OpenAPI в качестве отображаемого значения. По умолчанию name.

  • field_type (type) – Определяет тип поля autocomplete_property для дальнейшего описания в схеме и преобразования этого типа из API. По умолчанию пропускается, но требуект объекты int`или `str.

  • use_prefetch (bool) – делает prefetch для значений на фронтенде в list-view. True по умолчанию.

  • make_link (bool) – Отображает значение как ссылку на модель. По умолчанию True.

  • dependence (dict) – словарь, где ключи - это имена полей из той же модели, а значения - названия query-фильтров. Если хотя бы одно из полей, от которых существует зависимость, не допускает null, обязательно или установлено в null, список автодополнения будет пустым, а поле окажется выключенным. Есть несколько специальных ключей dependence-словаря, с помощью которых можно получить данные, хранящиеся на фронтенде, не делая лишних запросов в базу данных: '<<pk>>' получает первичный ключ текущего экземпляра, '<<view_name>>' получает имя view из компонента Vue, '<<parent_view_name>>' получает имя родительского view из компонента Vue, '<<view_level>>' получает уровень view, '<<operation_id>>' получает operation_id, '<<parent_operation_id'>> получает родительский operation_id.

Примеры:
field = FkField(select=Category, dependence={'<<pk>>': 'my_filter'})

Этот фильтр получит первичный ключ текущего объекта и сделает запрос на фронтенде „/category?my_filter=3“, где „3“ - первичный ключ текущего экземпляра.

Параметры:

filters (dict) – словарь, где ключи - это имена поля связанной модели, а значения - значения этого поля.

Примечание

Пересечение dependence.values() и filters.keys() выкинет ошибку для предотвращения неоднозначности при фильтрации.

Примечание

Действует только в графическом интерфейсе. Работает аналогично rest_framework.fields.IntegerField в API.

class vstutils.api.fields.FkModelField(*args, **kwargs)[исходный код]

Расширяет FkField, но хранит указанный класс модели. Это поле полезно для установки полей django.db.models.ForeignKey в модели.

Параметры:
  • select (vstutils.models.BModel,vstutils.api.serializers.VSTSerializer) – класс модели (основанный на vstutils.models.BModel) или сериализатор, используемый в API и имеющий свой путь в схеме OpenAPI.

  • autocomplete_property (str) – этот аргумент указывает, какие атрибуты будут взяты из model definition схемы OpenAPI в качестве используемого значения. По умолчанию id.

  • autocomplete_represent – этот аргумент указывает, какие атрибуты будут взяты из model definition схемы OpenAPI в качестве отображаемого значения. По умолчанию name.

  • use_prefetch – делает prefetch для значений на фронтенде в list-view. True по умолчанию.

  • make_link – Отображает значение как ссылку на модель. По умолчанию True.

Предупреждение

Класс модели получает объект из базы данных в процессе выполнения .to_internal_value. Будьте осторожны при выполнении массовых сохранений.

Предупреждение

Permission’ы модели, на которую ссылается это поле, не проверяются. Следует их проверять вручную в сигналах или валидаторах.

class vstutils.api.fields.HtmlField(*args, **kwargs)[исходный код]

Поле, содержащее текст html и помеченное как format:html. Это поле не проверяет, является ли его содержимое валидным HTML.

Предупреждение

Чтобы избежать уязвимости, не позволяйте пользователям изменять эти данные, так как они могут выполнить нежелательный скрипт.

Примечание

Действует только в графическом интерфейсе. Работает аналогично VSTCharField в API.

class vstutils.api.fields.MaskedField(*args, **kwargs)[исходный код]

Расширяет класс „rest_framework.serializers.CharField“. Поле, применяющее маску к значению.

Параметры:

mask (dict, str) – IMask

Примечание

Действует только на фронтенде.

class vstutils.api.fields.MultipleNamedBinaryFileInJsonField(*args, **kwargs)[исходный код]

Расширяет NamedBinaryFileInJsonField, но использует список JSON’ов. Позволяет оперировать несколькими файлами через список объектов NamedBinaryFileInJsonField.

Атрибуты: NamedBinaryInJsonField.file: если True, принимает только подклассы File в качестве входных данных. Если False, принимает только значения типа string. По умолчанию: False.

file_field

alias of MultipleFieldFile

class vstutils.api.fields.MultipleNamedBinaryImageInJsonField(*args, **kwargs)[исходный код]

Расширяет MultipleNamedBinaryFileInJsonField, но использует список JSON’ов. Используется для оперирования несколькими изображениями и работает как список объектов NamedBinaryImageInJsonField.

Параметры:

background_fill_color (str) – Цвет для заполнения области, не покрытой изображением после обрезки. По умолчанию прозрачный, но будет черным, если формат изображения не поддерживает прозрачность. Может быть любым допустимым цветом CSS.

class vstutils.api.fields.NamedBinaryFileInJsonField(*args, **kwargs)[исходный код]

Поле, принимающее на вход JSON со следующими свойствами: * name - string - имя файла; * mediaType - string - MIME-тип файла; * content - base64 string - содержимое файла.

Это поле полезно для сохранения бинарных файлов с их именами в полях модели django.db.models.CharField или django.db.models.TextField. Все операции по кодированию или декодированию бинарного содержимого осуществляется на клиенте. Это накладывает разумные ограничения на размер файла.

Кроме того, это поле может создать django.core.files.uploadedfile.SimpleUploadedFile из входящего JSON и сохранить его как файл в django.db.models.FileField, если для аргумента file установлено значение True

Атрибуты: NamedBinaryInJsonField.file: если True, принимает только подклассы File в качестве входных данных. Если False, принимает только значения типа string. По умолчанию: False.

Примечание

Действует только в графическом интерфейсе. Работает аналогично VSTCharField в API.

class vstutils.api.fields.NamedBinaryImageInJsonField(*args, **kwargs)[исходный код]

Расширяет NamedBinaryFileInJsonField для view изображения на фронтенде (если бинарное изображение валидно). Валидируйте это поле с помощью vstutils.api.validators.ImageValidator.

Параметры:

background_fill_color (str) – Цвет для заполнения области, не покрытой изображением после обрезки. По умолчанию прозрачный, но будет черным, если формат изображения не поддерживает прозрачность. Может быть любым допустимым цветом CSS.

class vstutils.api.fields.PasswordField(*args, **kwargs)[исходный код]

Расширяет CharField, но в схеме имеет format = password. В пользовательском интерфейсе отображает все символы как звездочки вместо реально введенных данных.

class vstutils.api.fields.PhoneField(*args, **kwargs)[исходный код]

Расширяет класс „rest_framework.serializers.CharField“. Поле для ввода номера телефона в международном формате

class vstutils.api.fields.QrCodeField(*args, **kwargs)[исходный код]

Простое строковое поле. В пользовательском интерфейсе оно будет отображено как QR-код.

Параметры:

child (rest_framework.fields.Field) – поле для сериализации или десериализации оригинальных данных.По умолчанию: rest_framework.fields.CharField

class vstutils.api.fields.RatingField(min_value=0, max_value=5, step=1, front_style='stars', **kwargs)[исходный код]

Расширяет класс „rest_framework.serializers.FloatField“. Это поле представляет собой ввод рейтинга пользователем на фронтенде. Пределы оценок могут быть заданы с помощью „min_value=“ и „max_value=“, по умолчанию 0 и 5 соответственно. Минимальный шаг между оценками определяется параметром „step=“, по умолчанию 1. Внешний вид на фронтенде может быть выбран с помощью „front_style=“, доступные варианты перечислены в „self.valid_front_styles“.

Для стиля „slider“ вы можете указать цвет слайдера, передав валидный цвет в „color=“. Для стиля „fa_icon“ вы можете указать иконку FontAwesome, которая будет использована для отображения рейтинга, передав валидный код иконки FontAwesome в „fa_class=“.

Параметры:
  • min_value (float, int) – минимальный уровень

  • max_value (float, int) – максимальный уровень

  • step (float, int) – минимальный шаг между уровнями

  • front_style (str) – визуализация поля на фронтенде. Допустимы: [„stars“, „slider“, „fa_icon“].

  • color (str) – цвет элемента рейтинга (star, icon или slider) в формате css

  • fa_class (str) – код иконки FontAwesome

class vstutils.api.fields.RedirectCharField(*args, **kwargs)[исходный код]

Поле для редиректа по строке. Часто используется в экшенах для редиректа после выполнения.

Примечание

Действует только в графическом интерфейсе. Работает аналогично rest_framework.fields.IntegerField в API.

class vstutils.api.fields.RedirectFieldMixin(**kwargs)[исходный код]

Миксина поля, указывающая, что это поле используется для отправки адреса редиректа после некоторого действия.

Параметры:
  • operation_name (str) – префикс для operation_id, например, если operation_id = history_get, то operation_name = history

  • depend_field (str) – имя поля, от которого оно зависит, его значение будет использовано для operation_id

  • concat_field_name (bool) – если True, то имя поля будет добавлено в конец operation_id

class vstutils.api.fields.RedirectIntegerField(*args, **kwargs)[исходный код]

Поля для редиректа по id. Часто используется в экшенах для редиректа после выполнения.

Примечание

Действует только в графическом интерфейсе. Работает аналогично rest_framework.fields.IntegerField в API.

class vstutils.api.fields.RelatedListField(related_name, fields, view_type='list', serializer_class=None, **kwargs)[исходный код]

Расширяет класс VSTCharField. С этим полем вы можете получить обратное ForeignKey отношение как список связанных экземпляров.

Для использования следует указать kwarg „related_name“ (related_manager для обратного ForeignKey) и kwarg „fields“ (список или кортеж полей из связанной модели, которая должна быть включена).

По умолчанию VSTCharField используется для сериализации всех значений поля и отображения их на фронтенде. Вы можете указать serializer_class и переопределить поля, которые вам нужны. Например, title, description или другие поля, свойства которых можно задать так, чтобы определить новое поведение на фронтенде.

Параметры:
  • related_name (str) – имя related manager’a для обратного foreign key отношения

  • fields (list[str], tuple[str]) – список связанных полей модели.

  • view_type (str) – определяет, как поля будут отображены на фронтенде. Должен быть либо „list“, либо „table“.

  • fields_custom_handlers_mapping (dict) – включает пользовательские handler’ы, где ключ: field_name, значение: callable_obj, который принимает параметры: instance[dict], fields_mapping[dict], model, field_name[str]

  • serializer_class (type) – Сериализатор для определения типов полей, если не задано, будет использован VSTCharField для каждого поля из списка fields

class vstutils.api.fields.SecretFileInString(*args, **kwargs)[исходный код]

Поле, расширяющее FileInStringField, но скрывающее свое значение в интерфейсе администратора.

Поле должно быть текстовым (не бинарным). Сохраняется в модель как есть.

Параметры:

media_types (tuple,list) – Список MIME-типов, доступных для выбора пользователем. Поддерживается синтаксис с использованием *. По умолчанию ['*/*']

Примечание

Действует только в графическом интерфейсе. В API ведет себя так же, как и VSTCharField.

class vstutils.api.fields.TextareaField(*args, **kwargs)[исходный код]

Поле, содержащее многострочный текст.

Примечание

Действует только в графическом интерфейсе. Работает аналогично VSTCharField в API.

class vstutils.api.fields.UptimeField(*args, **kwargs)[исходный код]

Поле продолжительности времени, в секундах. Может быть использовано для подсчета времени работы чего-либо.

Примечание

Действует только в графическом интерфейсе. Работает аналогично rest_framework.fields.IntegerField в API.

class vstutils.api.fields.VSTCharField(*args, **kwargs)[исходный код]

CharField (расширяет rest_framework.fields.CharField). Это поле преобразует любой json в строку для модели.

class vstutils.api.fields.WYSIWYGField(*args, **kwargs)[исходный код]

На фронтенде отображается https://ui.toast.com/tui-editor. Сохраняет данные в формате markdown, экранируя все html-теги.

Параметры:

escape (bool) – экранирование входящих html-символов. Включено по умолчанию.

Валидаторы

Классы для валидации полей.

class vstutils.api.validators.FileMediaTypeValidator(extensions=None, **kwargs)[исходный код]

Базовый класс для валидации изображений. Проверяет media types.

Параметры:

extensions (typing.Union[typing.Tuple, typing.List, None]) – Кортеж или список файловых расширений, которые должны проходить проверку.

Выбрасывает rest_framework.exceptions.ValidationError в случае, если расширение файла не присутствует в списке

class vstutils.api.validators.ImageBaseSizeValidator(extensions=None, **kwargs)[исходный код]

Проверяет размер изображения. Чтобы использовать этот класс для валидации ширины или высоты, переопределите self.orientation в („height“,), („width“,) или („height“, „width“)

Выбрасывает rest_framework.exceptions.ValidationError, если not(min <= (height or width) <= max)

Параметры:

extensions (typing.Union[typing.Tuple, typing.List, None]) –

class vstutils.api.validators.ImageHeightValidator(extensions=None, **kwargs)[исходный код]

Обертка для ImageBaseSizeValidator, проверяющая только высоту

Параметры:
  • min_height – минимальная валидная высота изображения

  • max_height – максимальная валидная высота изображения

  • extensions (typing.Union[typing.Tuple, typing.List, None]) –

class vstutils.api.validators.ImageOpenValidator(extensions=None, **kwargs)[исходный код]

Валидатор изображения, который проверяет, может ли изображения быть распаковано из b64 в объект PIL Image. Не будет работать, если не установлен Pillow.

Выбрасывает rest_framework.exceptions.ValidationError, если PIL выбрасывает ошибку при попытке открыть изображение

Параметры:

extensions (typing.Union[typing.Tuple, typing.List, None]) –

class vstutils.api.validators.ImageResolutionValidator(extensions=None, **kwargs)[исходный код]

Обертка для ImageBaseSizeValidator, проверяющая как высоту, так и ширину.

Параметры:
  • min_height – минимальная валидная высота изображения

  • max_height – максимальная валидная высота изображения

  • min_width – минимальная валидная ширина изображения

  • max_width – максимальная валидная ширина изображения

  • extensions (typing.Union[typing.Tuple, typing.List, None]) –

class vstutils.api.validators.ImageValidator(extensions=None, **kwargs)[исходный код]

Базовый класс для валидации изображения. Проверяет формат изображения. Не будет работать, если Pillow не установлен. Базовый класс для валидации изображения. Проверяет media types.

Параметры:

extensions (typing.Union[typing.Tuple, typing.List, None]) – Кортеж или список файловых расширений, которые должны проходить проверку.

Выбрасывает rest_framework.exceptions.ValidationError в случае, если расширение файла не присутствует в списке

property has_pillow

Проверьте, установлен ли Pillow

class vstutils.api.validators.ImageWidthValidator(extensions=None, **kwargs)[исходный код]

Обертка для ImageBaseSizeValidator, проверяющая только ширину

Параметры:
  • min_width – минимальная валидная ширина изображения

  • max_width – максимальная валидная ширина изображения

  • extensions (typing.Union[typing.Tuple, typing.List, None]) –

class vstutils.api.validators.RegularExpressionValidator(regexp=None)[исходный код]

Класс для валидации на основе регулярного выражения

Исключение:

rest_framework.exceptions.ValidationError – в случае, если значение не соответствует регулярному выражению

Параметры:

regexp (typing.Optional[typing.Pattern]) –

class vstutils.api.validators.UrlQueryStringValidator(regexp=None)[исходный код]

Класс для валидации строки url query, например a=&b=1

Параметры:

regexp (typing.Optional[typing.Pattern]) –

vstutils.api.validators.resize_image(img, width, height)[исходный код]

Вспомогательная функция для изменения размера изображения пропорционально определенным значениям. Может создать белые поля в случае, если это необходимо для удовлетворения требуемого размера

Параметры:
  • img (PIL.Image) – объект Pillow Image

  • width (int) – Необходимая ширина

  • height (int) – Необходимая высота

Результат:

объект Pillow Image

Тип результата:

PIL.Image

vstutils.api.validators.resize_image_from_to(img, limits)[исходный код]

Вспомогательная функция для изменения размера изображения пропорционально значениям между минимальным и максимальным значениями для каждой стороны. Может создать белые поля, если это необходимо для соблюдения ограничений

Параметры:
  • img (PIL.Image) – объект Pillow Image

  • limits (dict) – Словарь с максимальным/минимальным ограничениями, например {'width': {'min': 300, 'max: 600'}, 'height':  {'min': 400, 'max: 800'}}

Результат:

объект Pillow Image

Тип результата:

PIL.Image

Сериализаторы

Стандартные классы сериализаторов для web-api. Читайте подробнее в документации сериализаторов Django REST Framework Serializers.

class vstutils.api.serializers.BaseSerializer(*args, **kwargs)[исходный код]

Стандартный сериализатор с логикой работы с объектами. Читайте подробнее в документации сериализатора как создавать сериализаторы и работать с ними.

Примечание

Вы также можете настроить generated_fields в атрибуте класса Meta, чтобы получить сериализатор с полями CharField по умолчанию. Настройте атрибут generated_field_factory чтобы изменить фабричный метод по умолчанию.

class vstutils.api.serializers.EmptySerializer(*args, **kwargs)[исходный код]

Стандартный сериализатор для пустых ответов. В сгенерированном графическом интерфейсе это означает, что кнопка действия не будет отображать дополнительного view перед запуском.

class vstutils.api.serializers.VSTSerializer(*args, **kwargs)[исходный код]

Стандартный сериализатор модели, основанный на rest_framework.serializers.ModelSerializer. Читайте подробнее в документации DRF, как создавать сериализаторы модели. Этот сериализатор сопоставляет полям модели расширенный набор полей сериализатора. Список доступных пар описан в VSTSerializer.serializer_field_mapping. Например, чтобы использовать vstutils.api.fields.FkModelField в сериализаторе, задайте vstutils.models.fields.FkModelField в модели.

Представления

Стандартные ViewSet’ы для web-api.

class vstutils.api.base.CopyMixin(**kwargs)[исходный код]

Миксина для viewset’ов, добавляющая copy endpoint во view.

copy(request, **kwargs)[исходный код]

Endpoint, который копирует экземпляр с его зависимостями.

Параметры:

request (rest_framework.request.Request) –

Тип результата:

vstutils.api.responses.BaseResponseClass

copy_field_name = 'name'

Имя поля, которое получит префикс.

copy_prefix = 'copy-'

Значение префикса, которое будет добавлено к новому имени экземпляра.

Список связанных имен, которые будут скопированы в новый экземпляр.

class vstutils.api.base.FileResponseRetrieveMixin(**kwargs)[исходный код]

Миксина ViewSet для получения FileResponse из моделей с файловыми полями.

Пример:

import datetime
import os
from django.db import models
from django.db.models.functions import Now
from rest_framework import permissions, fields as drf_fields
from vstutils.api.serializers import BaseSerializer, DataSerializer
from vstutils.models.decorators import register_view_action
from vstutils.models.custom_model import ListModel, FileModel, ViewCustomModel
from vstutils.api import fields, base, responses

from .cacheable import CachableModel


class TestQuerySerializer(BaseSerializer):
    test_value = drf_fields.ChoiceField(required=True, choices=("TEST1", "TEST2"))


class FileViewMixin(base.FileResponseRetrieveMixin):
    # required always
    instance_field_data = 'value'
    # required for response caching in browser
    instance_field_timestamp = 'updated'
    @register_view_action(
        methods=['get'],
        detail=False,
        query_serializer=TestQuerySerializer,
        serializer_class=DataSerializer,
        suffix='Instance'
    )
    def query_serializer_test(self, request):
        query_validated_data = self.get_query_serialized_data(request)
        return responses.HTTP_200_OK(query_validated_data)

    @register_view_action(
        methods=['get'],
        detail=False,
        query_serializer=TestQuerySerializer,
        is_list=True
    )
    def query_serializer_test_list(self, request):
        return self.list(request)
serializer_class_retrieve

alias of FileResponse

class vstutils.api.base.GenericViewSet(**kwargs)[исходный код]

Базовый класс для всех view. Расширяет стандартные функции классов DRF. Здесь представлены некоторые из возможностей:

  • Предоставляет атрибуты model вместо queryset.

  • Позволяет устанавливать сериализаторы отдельно для каждого экшена через словарь action_serializers или атрибуты, имя которых соответствует шаблону serializer_class_[action name].

  • Позволяет отдельно указать сериализаторы для view списков и детальной записи.

  • Оптимизирует запросы в базу данных для GET-запросов, делая выборку, если возможно, только тех полей, которые нужны сериализатору.

create_action_serializer(*args, **kwargs)[исходный код]

Метод, реализующий стандартную логику экшенов. Он опирается на переданные аргументы для построения логики. Поэтому, если был передан именованный аргумент, сериализатор будет подвержен валидации и сохранен.

Параметры:
  • autosave (bool) – Включает/выключает выполнение сохранения сериализатором, если передан именованный аргумент data. Включено по умолчанию.

  • custom_data (dict) – Словарь с данными, которые будут переданы в validated_data без валидации.

  • serializer_class (None,type[rest_framework.serializers.Serializer]) – Класс сериализатора для текущего выполнения. Может быть полезно, когда сериализаторы запроса и ответа различны.

параметр:

data: Стандартный аргумент класса сериализатора с сериализуемыми данными. Включает в себя валидацию и сохранение.

параметр:

instance: Стандартный аргумент класса сериализатора с сериализуемым экземпляром.

Результат:

Готовый сериализатор с логикой выполнения по умолчанию.

Тип результата:

rest_framework.serializers.Serializer

get_query_serialized_data(request, query_serializer=None, raise_exception=True)[исходный код]

Позволяет получить данные запроса и сериализовать значения, если существует атрибут query_serializer_class или атрибут был передан.

Параметры:
  • request (rest_framework.request.Request) – объект DRF запроса.

  • query_serializer (typing.Type[rest_framework.serializers.BaseSerializer]) – класс сериализатора, для обработки параметров в query_params.

  • raise_exception (bool) – флаг, который говорит о том нужно ли выбросить исключение при валидации в сериализаторе или нет.

Тип результата:

typing.Union[dict, collections.OrderedDict]

get_serializer(*args, **kwargs)[исходный код]

Возвращает экземпляр сериализатора, который должен быть использован для валидации и десериализации входных данных, и сериализации выходных данных.

Позволяет использовать django.http.StreamingHttpResponse в качестве инициализации сериализатора.

Параметры:
Тип результата:

rest_framework.serializers.BaseSerializer

get_serializer_class()[исходный код]

Позволяет задать класс сериализатора для каждого экшена.

nested_allow_check()[исходный код]

Просто выбросьте исключение или пропустите (pass). Используется во вложенных view для упрощения проверки доступа.

class vstutils.api.base.HistoryModelViewSet(**kwargs)[исходный код]

Стандартный viewset, как, например ReadOnlyModelViewSet, но для данных исторического характера (позволяет удалять записи, но не создавать или обновлять). Наследуется от GenericViewSet.

class vstutils.api.base.ModelViewSet(**kwargs)[исходный код]

Viewset, предоставляющий CRUD-экшены над моделью. Наследуется от GenericViewSet.

Переменные:
Примеры:
from vstutils.api.base import ModelViewSet
from . import serializers as sers


class StageViewSet(ModelViewSet):
    # This is difference with DRF:
    # we use model instead of queryset
    model = sers.models.Stage
    # Serializer for list view (view for a list of Model instances
    serializer_class = sers.StageSerializer
    # Serializer for page view (view for one Model instance).
    # This property is not required, if its value is the same as `serializer_class`.
    serializer_class_one = sers.StageSerializer
    # Allowed to set decorator to custom endpoint like this:
    # serializer_class_create - for create method
    # serializer_class_copy - for detail endpoint `copy`.
    # etc...
class vstutils.api.base.ReadOnlyModelViewSet(**kwargs)[исходный код]

Стандартный viewset, как, например vstutils.api.base.ModelViewSet для readonly-моделей. Наследуется от GenericViewSet.

class vstutils.api.decorators.nested_view(name, arg=None, methods=None, *args, **kwargs)[исходный код]

По умолчанию DRF не поддерживает вложенные view. Данный декоратор решает эту проблему.

Вам нужны две или более модели с вложенными отношениями (многие-ко-многим или многие-к-одному) и два viewset’а. Декоратор вкладывает viewset’ы в родительский класс viewset’ов и генерирует пути в API.

Параметры:
  • name (str) – Имя вложенного пути. Также используется стандартное имя для связанных queryset’ов (см. manager_name).

  • arg (str) – Имя вложенного поля первичного ключа.

  • view (vstutils.api.base.ModelViewSet, vstutils.api.base.HistoryModelViewSet, vstutils.api.base.ReadOnlyModelViewSet) – Класс вложенного viewset’а.

  • allow_append (bool) – Флаг, разрешающий добавление существующих экземпляров.

  • manager_name (str,Callable) – Имя атрибута объекта модели, который содержит вложенный queryset.

  • methods (list) – Список разрешенных методов для endpoint’ов вложенных view.

  • subs (list,None) – Список разрешенных subviews или экшенов для endpoint’ов вложенных views.

  • queryset_filters – Список вызываемых объектов, которые возвращают отфильтрованный queryset.

Примечание

Некоторые методы view не будут вызваны из соображений производительности. Это также применяется к некоторым атрибутам класса, которые обычно инициализируются в методах. Например, .initial() никогда не будет вызван. Каждый viewset обернут вложенным классом с дополнительной логикой.

Пример:

from vstutils.api.decorators import nested_view
from vstutils.api.base import ModelViewSet
from . import serializers as sers


class StageViewSet(ModelViewSet):
    model = sers.models.Stage
    serializer_class = sers.StageSerializer


nested_view('stages', 'id', view=StageViewSet)
class TaskViewSet(ModelViewSet):
    model = sers.models.Task
    serializer_class = sers.TaskSerializer

Данный код генерирует пути api:

  • /tasks/ - GET, POST

  • /tasks/{id}/ - GET, PUT, PATCH, DELETE

  • /tasks/{id}/stages/ - GET, POST

  • /tasks/{id}/stages/{stages_id}/ - GET, PUT, PATCH, DELETE

vstutils.api.decorators.subaction(*args, **kwargs)[исходный код]

Декоратор, оборачивающий метод объекта в subaction viewset’а.

Параметры:
  • methods – Список разрешенных методов HTTP. По умолчанию ["post"].

  • detail – Флаг, указывающий, должен ли метод применяться к одному экземпляру.

  • serializer_class – Сериализатор для этого экшена.

  • permission_classes – Кортеж или список permission-классов.

  • url_path – Имя API-пути для этого экшена.

  • description – Описание этого экшена в OpenAPI.

  • multiaction – Разрешает использовать этот экшен в мультиэкшенах. Работает только с vstutils.api.serializers.EmptySerializer в response.

  • require_confirmation – Задает, должен ли экшен требовать подтверждения перед выполнением.

  • is_list – Отметить это действие как пагинируемый список со всеми правилами и параметрами.

  • title – Заменить заголовок действия.

  • icons – Настроить классы иконок действия.

Actions (Действия)

Vstutils имеет развитую систему работы с действиями. REST API работает с данными через глаголы, которые называются методами. Однако для работы с одной или списком сущностей этих действий может быть недостаточно.

Чтобы расширить набор действий, необходимо создать действие, которое будет работать с некоторым аспектом описанной модели. Для этих целей существует стандартный rest_framework.decorators.action(), который также можно расширить с помощью схемы. Но для большего удобства в vstutils есть набор декораторов, которые позволяют избежать написания

Основная философия этих оберток заключается в том, что разработчик пишет бизнес-логику, не отвлекаясь на написание повторяющегося кода. Часто большинство ошибок в коде возникают именно из-за расфокусировки внимания при рутинном написании кода.

class vstutils.api.actions.Action(detail=True, methods=None, serializer_class=<class 'vstutils.api.serializers.DataSerializer'>, result_serializer_class=None, query_serializer=None, multi=False, title=None, icons=None, is_list=False, hidden=False, **kwargs)[исходный код]

Базовый класс действий. Обладает минимально необходимой функциональностью для создания действия и позволяет написать только бизнес-логику. Этот декоратор подходит в случаях, когда невозможно реализовать логику с использованием SimpleAction или алгоритм значительно более сложный, чем стандартные операции CRUD.

Примеры:

...
from vstutils.api.fields import VSTCharField
from vstutils.api.serializers import BaseSerializer
from vstutils.api.base import ModelViewSet
from vstutils.api.actions import Action
...

class RequestSerializer(BaseSerializer):
    data_field1 = ...
    ...


class ResponseSerializer(BaseSerializer):
    detail = VSTCharField(read_only=True)


class AuthorViewSet(ModelViewSet):
    model = ...
    ...

    @Action(serializer_class=RequestSerializer, result_serializer_class=ResponseSerializer, ...)
    def profile(self, request, *args, **kwargs):
        ''' Got `serializer_class` body and response with `result_serializer_class`. '''
        serializer = self.get_serializer(self.get_object(), data=request.data)
        serializer.is_valid(raise_exception=True)
        return {"detail": "Executed!"}
Параметры:
  • detail (bool) – Флаг, указывающий, какой тип действия используется: на списке или на отдельной сущности. Влияет на то, где будет отображаться это действие - на детальной записи или на списке записей.

  • methods (typing.List[str]) – Список доступных методов HTTP. По умолчанию ["post"].

  • serializer_class (typing.Type[rest_framework.serializers.Serializer]) – Сериализатор для тела запроса. Используется также для формирования ответа по умолчанию.

  • result_serializer_class (typing.Type[rest_framework.serializers.Serializer]) – Сериализатор для тела ответа. Необходим, когда запрос и ответ имеют различные наборы полей.

  • query_serializer (typing.Type[rest_framework.serializers.Serializer]) – Сериализатор для данных запроса типа GET. Используется, когда необходимо получить корректные данные в строке запроса типа GET и привести их к нужному типу.

  • multi (bool) – Используется только с не-GET запросами и уведомляет GUI, что это действие должно быть применено к выбранным элементам списка.

  • title (str) – Заголовок действия в пользовательском интерфейсе. Для действий, отличных от GET, заголовок генерируется на основе имени метода.

  • icons (typing.Union[str, typing.Iterable]) – Список иконок для кнопки пользовательского интерфейса.

  • is_list (bool) – Флаг, указывающий, является ли тип действия списком или отдельной сущностью. Обычно используется с действиями GET.

  • kwargs – Набор именованных аргументов для rest_framework.decorators.action().

  • hidden (bool) –

class vstutils.api.actions.EmptyAction(**kwargs)[исходный код]

В этом случае действия с объектом не требуют каких-либо данных и манипуляций с ними. Для таких случаев существует стандартный метод, который позволяет упростить схему и код работы только с объектом.

При необходимости вы также можете переопределить сериализатор ответа, чтобы уведомить интерфейс о формате возвращаемых данных.

Примеры:

...
from vstutils.api.fields import RedirectIntegerField
from vstutils.api.serializers import BaseSerializer
from vstutils.api.base import ModelViewSet
from vstutils.api.actions import EmptyAction
...

class ResponseSerializer(BaseSerializer):
    id = RedirectIntegerField(operation_name='sync_history')


class AuthorViewSet(ModelViewSet):
    model = ...
    ...

    @EmptyAction(result_serializer_class=ResponseSerializer, ...)
    def sync_data(self, request, *args, **kwargs):
        ''' Example of action which get object, sync data and redirect user to another view. '''
        sync_id = self.get_object().sync().id
        return {"id": sync_id}
...
from django.http.response import FileResponse
from vstutils.api.base import ModelViewSet
from vstutils.api.actions import EmptyAction
...

class AuthorViewSet(ModelViewSet):
    model = ...
    ...

    @EmptyAction(result_serializer_class=ResponseSerializer, ...)
    def resume(self, request, *args, **kwargs):
        ''' Example of action which response with generated resume in pdf. '''
        instance = self.get_object()

        return FileResponse(
            streaming_content=instance.get_pdf(),
            as_attachment=True,
            filename=f'{instance.last_name}_{instance.first_name}_resume.pdf'
        )
class vstutils.api.actions.SimpleAction(*args, **kwargs)[исходный код]

Идея этого декоратора заключается в том, чтобы получить полный CRUD для экземпляра с минимумом шагов. Экземпляр - это объект, который возвращается из декорируемого метода. Весь механизм очень похож на стандартный декоратор property, с описанием getter, setter, и deleter

Если вы собираетесь создать точку входа для работы с отдельным объектом, то вам не нужно определять методы. Наличие getter`a, setter`a, и deleter`a определит, какие методы будут доступны.

В официальной документации Django приведен пример с перемещением данных, которые не являются важными для авторизации, в модель Profile. Для работы с такими данными, находящимися вне основной модели, существует данный объект действия, который реализует основную логику в наиболеавтоматизированном виде.

Он охватывает большинство задач по работе с такими данными. По умолчанию у него есть метод GET вместо POST. Кроме того, для лучшей организации кода он позволяет изменить методы, которые будут вызываться при изменении или удалении данных.

При назначении действия на объект список методов также заполняется необходимыми методами.

Примеры:

...
from vstutils.api.fields import PhoneField
from vstutils.api.serializers import BaseSerializer
from vstutils.api.base import ModelViewSet
from vstutils.api.actions import Action
...

class ProfileSerializer(BaseSerializer):
    phone = PhoneField()


class AuthorViewSet(ModelViewSet):
    model = ...
    ...

    @SimpleAction(serializer_class=ProfileSerializer, ...)
    def profile(self, request, *args, **kwargs):
        ''' Get profile data to work. '''
        return self.get_object().profile

    @profile.setter
    def profile(self, instance, request, serializer, *args, **kwargs):
        instance.save(update_fields=['phone'])

    @profile.deleter
    def profile(self, instance, request, serializer, *args, **kwargs):
        instance.phone = ''
        instance.save(update_fields=['phone'])

Filterset’ы

Для большего удобства разработки, фреймворк предоставляет дополнительные классы и функции для фильтрации элементов на основе полей.

class vstutils.api.filters.DefaultIDFilter(data=None, queryset=None, *, request=None, prefix=None)[исходный код]

Базовый filterset для поиска по id. Предоставляет поиск по множеству значений, разделенных запятой. Использует extra_filter() в полях.

class vstutils.api.filters.DefaultNameFilter(data=None, queryset=None, *, request=None, prefix=None)[исходный код]

Базовый filterset для частичного поиска по названию. Использует условие LIKE в базе данных с помощью name_filter().

class vstutils.api.filters.FkFilterHandler(related_pk='id', related_name='name', pk_handler=<class 'int'>)[исходный код]

Простой handler для фильтрации по связанным полям.

Параметры:
  • related_pk (str) – Имя поля первичного ключа в связанной модели. По умолчанию „id“.

  • related_name (str) – Имя charfield-поля в связанной модели. По умолчанию „name“.

  • pk_handler (typing.Callable) – Изменяет handler для проверки значения перед поиском. Посылает «0», если handler падает. По умолчанию используется int().

Пример:
class CustomFilterSet(filters.FilterSet):
    author = CharFilter(method=vst_filters.FkFilterHandler(related_pk='pk', related_name='email'))

Где author - это ForeignKey на User, и вы хотите искать по первичному ключу и полю email.

vstutils.api.filters.extra_filter(queryset, field, value)[исходный код]

Метод, предназначенный для поиска значений в списке значений, разделенных запятой.

Параметры:
  • queryset (django.db.models.query.QuerySet) – queryset модели для фильтрации.

  • field (str) – имя поля в FilterSet’е. Также поддерживает суффикс __not.

  • value (str) – список искомых значений, разделенных запятыми.

Результат:

отфильтрованный queryset.

Тип результата:

django.db.models.query.QuerySet

vstutils.api.filters.name_filter(queryset, field, value)[исходный код]

Метод для частичного поиска по названию. Использует условие LIKE базы данных или выражение contains queryset’а.

Параметры:
  • queryset (django.db.models.query.QuerySet) – queryset модели для фильтрации.

  • field (str) – имя поля в FilterSet’е. Также поддерживает суффикс __not.

  • value (str) – часть названия для поиска.

Результат:

отфильтрованный queryset.

Тип результата:

django.db.models.query.QuerySet

Ответы (responses)

DRF предоставляет стандартный набор переменных, удобочитаемые названия которых соответствуют HTTP-кодам ответов. Для удобства мы динамически оборачиваем их в набор классов с соответствующими именами и дополнительно обеспечиваем следующие возможности:

  • Строковые ответы оборачиваются в json, например { "detail": "string response" }.

  • Тайминги атрибутов сохраняются для дальнейшей обработки в middleware.

  • Код состояния задается именем класса (например HTTP_200_OK или Response200 имеют код 200).

Все классы наследуются от:

class vstutils.api.responses.BaseResponseClass(*args, **kwargs)[исходный код]

Класс ответа API со стандартным кодом состояния.

Переменные:
  • status_code (int) – Код состояния HTTP.

  • timings (int,None) – Тайминги ответов.

Параметры:

timings – Тайминги ответов.

Middleware

По умолчанию Django предполагает, что разработчик создает класс Middleware вручную, однако зачастую это рутинная задача. Библиотека vstutils предлагает удобный класс request handler’а для изящной разработки в стиле ООП. Middleware используются для обработки входящих запросов и отправления ответов до того, как они достигнут получателя.

class vstutils.middleware.BaseMiddleware(get_response)[исходный код]

Базовый класс middleware для обработки:

Middleware должен быть добавлен в список MIDDLEWARE, находящийся в настройках.

Пример:
from vstutils.middleware import BaseMiddleware
from django.http import HttpResponse


class CustomMiddleware(BaseMiddleware):
    def request_handler(self, request):
        # Add header to request
        request.headers['User-Agent'] = 'Mozilla/5.0'
        return request

    def get_response_handler(self, request):
        if not request.user.is_stuff:
            # Return 403 HTTP status for non-stuff users.
            # This request never gets in any view.
            return HttpResponse(
                "Access denied!",
                content_type="text/plain",
                status_code=403
            )
        return super().get_response_handler(request)

    def handler(self, request, response):
        # Add header to response
        response['Custom-Header'] = 'Some value'
        return response
Параметры:

get_response (typing.Callable) –

get_response_handler(request)[исходный код]

Точка входа для прерывания или продолжения обработки запроса. Эта функция должна возвращать объект django.http.HttpResponse или результат вызова родительского класса.

Начиная с релиза 5.3, было возможно написать этот метод асинхронным. Это должно использоваться в тех случаях, когда middleware делает запросы к базе данных или к кэшу. Однако такой компонент middleware должен быть исключен из bulk запросов.

Предупреждение

Никогда не делайте асинхронным middleware в цепях зависимостей. Они разработаны, чтобы отправлять независимые запросы к внешним ресурсам.

Установите async_capable в True и sync_capable в False для таких middleware.

Параметры:

request (django.http.HttpRequest) – Объект HTTP-запроса, созданный из клиентского запроса.

Тип результата:

django.http.HttpResponse

handler(request, response)[исходный код]

Handler ответа. Метод для обработки ответов.

Параметры:
Результат:

Обработанный объект ответа.

Тип результата:

django.http.HttpResponse

request_handler(request)[исходный код]

Handler запроса. Вызывается перед обработкой запроса view.

Параметры:

request (django.http.HttpRequest) – Объект HTTP-запроса, созданный из клиентского запроса.

Результат:

Обработанный объект запроса.

Тип результата:

django.http.HttpRequest

Filter Backend’ы

Filter Backend’ы используются для изменения queryset’а модели. Чтобы создать пользовательский filter backend (т.е. аннотировать queryset модели), следует наследоваться от vstutils.api.filter_backends.VSTFilterBackend и переопределить vstutils.api.filter_backends.VSTFilterBackend.filter_queryset(). В некоторых случаях также стоит переопределить vstutils.api.filter_backends.VSTFilterBackend.get_schema_fields().

class vstutils.api.filter_backends.DeepViewFilterBackend[исходный код]

Backend, фильтрующий queryset по колонке из свойства deep_parent_field модели. Значение для фильтрации должно быть передано в query-параметре __deep_parent.

Если параметр отсутствует, то никакие фильтры не применяются.

Если параметр - это пустое значение (/?__deep_parent=), то возвращаются объекты, не имеющие родителя (значение поля, чье имя хранится в свойстве модели deep_parent_field, равно None).

Этот filter backend и вложенное view автоматически добавляются в случае, если модель имеет свойство deep_parent_field.

Пример:
from django.db import models
from vstutils.models import BModel

class DeepNestedModel(BModel):
    name = models.CharField(max_length=10)
    parent = models.ForeignKey('self', null=True, default=None, on_delete=models.CASCADE)

    deep_parent_field = 'parent'
    deep_parent_allow_append = True

    class Meta:
        default_related_name = 'deepnested'

В примере выше если мы добавим эту модель под путь „deep“, следующие view будут созданы: /deep/ и /deep/{id}/deepnested/.

Filter backend, который может быть использован как /deep/?__deep_parent=1, и будет возвращать все объекты DeepNestedModel, чьи родительские первичные ключи равны 1.

Вы также можете использовать generic-view DRF. Для этого все еще нужно задать deep_parent_field вашей модели и вручную добавить DeepViewFilterBackend в список filter_backends.

class vstutils.api.filter_backends.HideHiddenFilterBackend[исходный код]

Filter Backend, убирающий из queryset все объекты, у которых задан атрибут hidden=True.

filter_queryset(request, queryset, view)[исходный код]

Очищает объекты со атрибутом hidden из queryset’а.

class vstutils.api.filter_backends.SelectRelatedFilterBackend[исходный код]

Filter Backend, автоматически вызывающий prefetch_related и select_related для всех отношений в queryset’е.

filter_queryset(request, queryset, view)[исходный код]

Выполняет select и prefetch в queryset’е.

class vstutils.api.filter_backends.VSTFilterBackend[исходный код]

Базовый класс filter backend’а, от которого следует наследоваться. Пример:

from django.utils import timezone
from django.db.models import Value, DateTimeField

from vstutils.api.filter_backends import VSTFilterBackend

class CurrentTimeFilterBackend(VSTFilterBackend):
    def filter_queryset(self, request, queryset, view):
        return queryset.annotate(current_time=Value(timezone.now(), output_field=DateTimeField()))

В данном примере Filter Backend аннотирует время в текущем часовом поясе в queryset’е используемой модели.

В некоторых случаях может быть необходимо передать параметр из query запроса. Чтобы определить этот параметр в схеме, вы должны перегрузить функцию get_schema_operation_parameters и указать список параметров, которые нужно использовать.

Пример:

from django.utils import timezone
from django.db.models import Value, DateTimeField

from vstutils.api.filter_backends import VSTFilterBackend

class ConstantCurrentTimeForQueryFilterBackend(VSTFilterBackend):
    query_param = 'constant'

    def filter_queryset(self, request, queryset, view):
        if self.query_param in request.query_params and request.query_params[self.query_param]:
            queryset = queryset.annotate(**{
                request.query_params[self.query_param]: Value(timezone.now(), output_field=DateTimeField())
            })
        return queryset

        def get_schema_operation_parameters(self, view):
            return [
                {
                    "name": self.query_param,
                    "required": False,
                    "in": openapi.IN_QUERY,
                    "description": "Annotate value to queryset",
                    "schema": {
                        "type": openapi.TYPE_STRING,
                    }
                },
            ]

В данном примере Filter Backend аннотирует время в текущем часовом поясе в queryset’е используемой модели именем поля из query constant.

get_schema_operation_parameters(view)[исходный код]

Вы также можете создать элементы управления фильтрами доступными для автогенерации схемы, предоставляемой REST-фреймворком, реализуя этот метод. Метод должен возвращать список OpenAPI сопоставлений схемы.

Celery

Celery - это распределенная очередь задач. Он используется для запуска задач асинхронно в отдельном worker’е. Чтобы узнать больше о Celery, смотрите официальную документацию. Для работы функций vstutils, связанных с Celery, необходимо указать секции [rpc] and [worker] в settings.ini. Также вам понадобится установить дополнительные [rpc] зависимости.

Tasks

class vstutils.tasks.TaskClass[исходный код]

Обертка для класса BaseTask из Celery. Использование такое же, как и стандартного класса, однако вы можете запустить задачу без необходимости создавать экземпляр с помощью метода TaskClass.do().

Пример:

from vstutils.environment import get_celery_app
from vstutils.tasks import TaskClass

app = get_celery_app()

class Foo(TaskClass):
    def run(*args, **kwargs):
        return 'Foo task has been executed'

app.register_task(Foo())
Теперь вы можете вызвать задачу несколькими методами:
  • вызвав Foo.do(*args, **kwargs)

  • получить зарегистрированный экземпляр задачи можно так: app.tasks[„full_path.to.task.class.Foo“]

Также вы можете сделать вашу зарегистрированную задачу периодической. Для этого нужно добавить ее CELERY_BEAT_SCHEDULE в settings.py:

CELERY_BEAT_SCHEDULE = {
    'foo-execute-every-month': {
        'task': 'full_path.to.task.class.Foo',
        'schedule': crontab(day_of_month=1),
    },
}
classmethod do(*args, **kwargs)[исходный код]

Метод, который посылает сигнал запуска удаленной задаче celery. Все аргументы будут переданы методу задачи TaskClass.run().

Тип результата:

celery.result.AsyncResult

property name

свойство для правильного выполнения Celery-задачи, нужно для работы метода TaskClass.do()

run(*args, **kwargs)

Тело задачи выполняется worker’ами.

Endpoint

Endpoint-view имеет две цели: выполнение bulk-запросов и предоставление схемы OpenAPI.

URL endpoint’а - /{API_URL}/endpoint/, например значение с настройками по умолчанию - /api/endpoint/.

API_URL может быть изменен в settings.py.

class vstutils.api.endpoint.EndpointViewSet(**kwargs)[исходный код]

Стандартный viewset API-endpoint’а.

get(request)[исходный код]

Возвращает ответ в виде Swagger UI или OpenAPI json-схему, если указан ?format=openapi

Параметры:

request (vstutils.api.endpoint.BulkRequestType) –

Тип результата:

django.http.response.HttpResponse

get_client(request)[исходный код]

Возвращает тестового клиента, гарантируя, что если bulk-запрос выполнен от аутентифицированного пользователя, то тестовый клиент будет аутентифицирован тем же самым пользователем.

Параметры:

request (vstutils.api.endpoint.BulkRequestType) –

Тип результата:

vstutils.api.endpoint.BulkClient

get_serializer(*args, **kwargs)[исходный код]

Возвращает экземпляр сериализатора, который должен быть использован для валидации и десериализации входных данных, и сериализации выходных данных.

Тип результата:

vstutils.api.endpoint.OperationSerializer

get_serializer_context(context)[исходный код]

Дополнительный контекст, предоставляемый классу сериализатора.

Тип результата:

dict

operate(operation_data, context)[исходный код]

Метод, используемый для обработки одной операции и возвращающий ее результат

Параметры:
Тип результата:

typing.Tuple[typing.Dict, typing.SupportsFloat]

post(request)[исходный код]

Выполнить транзакционный bulk-запрос

Параметры:

request (vstutils.api.endpoint.BulkRequestType) –

Тип результата:

vstutils.api.responses.BaseResponseClass

put(request, allow_fail=True)[исходный код]

Выполнить нетранзакционный bulk-запрос

Параметры:

request (vstutils.api.endpoint.BulkRequestType) –

Тип результата:

vstutils.api.responses.BaseResponseClass

serializer_class

Класс сериализатора одной операции.

alias of OperationSerializer

versioning_class

alias of QueryParameterVersioning

Bulk-запросы

Bulk-запрос позволяет вам отсылать несколько запросов к api в одном. Он принимает json-список операций.

Метод

Транзакционный (все операции в одной транзакции)

Синхронный (операции выполняются одна за другой в указанном порядке)

PUT /{API_URL}/endpoint/

НЕТ

ДА

POST /{API_URL}/endpoint/

ДА

ДА

PATCH /{API_URL}/endpoint/

НЕТ

НЕТ

Параметры одной операции (обязательный параметр помечается *):

  • method* - http-метод запроса

  • path* - путь запроса, может быть типа str или list

  • data - данные для отправки

  • query - query-параметры типа str

  • let - строка с именем переменной (используется для доступа к результату ответа в шаблонах)

  • headers - dict с заголовками, которые будут установлены, названия заголовков должны соблюдать спецификацию CGI (например CONTENT_TYPE, GATEWAY_INTERFACE, HTTP_*).

  • version - str с указанной версией api, если не задано, то используется VST_API_VERSION

В любой параметр запроса вы можете вставить результат значения предыдущей операции (<<{OPERATION_NUMBER or LET_VALUE}[path][to][value]>>), например:

[
    {"method": "post", "path": "user", "data": {"name": "User 1"}),
    {"method": "delete", "version": "v2", "path": ["user", "<<0[data][id]>>"]}
]

Результат bulk-запроса - это список json-объектов, описывающих операцию:

  • method - http-метод

  • path - путь запроса, всегда строка

  • data - данные, которые нужно отправить

  • status - код состояния ответа

Транзакционный bulk-запрос возвращает 502 BAG GATEWAY и делает откат к состоянию до запроса после первого неудачного запроса.

Предупреждение

Если вы отправили нетранзакционный bulk-запрос, вы получите код 200 и должны будете проверить статус каждого ответа операции отдельно.

Схема OpenAPI

Запрос на GET /{API_URL}/endpoint/ возвращает Swagger UI.

Запрос на GET /{API_URL}/endpoint/?format=openapi возвращает схему OpenAPI в формате json. Также вы можете указать нужную версию схемы, используя query-параметр version

Для изменения схемы после ее генерации и перед отправкой пользователю используйте хуки. Напишите одну или несколько функций, каждая из которых принимает 2 именованных аргумента:

  • request - объект запроса пользователя.

  • schema - ordered dict, содержащий схему OpenAPI.

Примечание

Иногда хуки могут выбросить исключение; чтобы сохранить цепочку модификации данных, такие исключения обрабатываются. Изменения, сделанные в схеме перед выбросом исключения, в любом случае сохраняются.

Пример хука:
def hook_add_username_to_guiname(request, schema):
    schema['info']['title'] = f"{request.username} - {schema['info']['title']}"

Чтобы присоединить хук(-и) к вашему приложению, добавьте строку импорта вашей функции в список OPENAPI_HOOKS в settings.py

OPENAPI_HOOKS = [
    '{{appName}}.openapi.hook_add_username_to_guiname',
]

Фреймворк для тестирования

Фреймворк VST Utils включает в себя хелпер в базовом тест-кейс классе и улучшает поддержку механизма отправки запросов. На практике это означает, что для отправления bulk-запроса на endpoint нет необходимости создавать и инициализировать test client, а можно сразу делать запрос.

endpoint_results = self.bulk([
    # list of endpoint requests
])

Создание тест-кейса

Модуль test.py содержит классы тест-кейсов, основанные на vstutils.tests.BaseTestCase. На текущий момент мы официально поддерживаем два подхода к написанию тестов: классический и с помощью оберток запросов с проверкой выполнения и runtime-оптимизацией bulk-запросов с ручной проверкой значений.

Простой пример с классическими тестами

Например, если у вас endpoint вида /api/v1/project/ и модель Project, вы можете написать такой тест:

from vstutils.tests import BaseTestCase


class ProjectTestCase(BaseTestCase):
    def setUp(self):
        super(ProjectTestCase, self).setUp()
        # init demo project
        self.initial_project = self.get_model_class('project.Test').objects.create(name="Test")

    def tearDown(self)
        super(ProjectTestCase, self).tearDown()
        # remove it after test
        self.initial_project.delete()

    def test_project_endpoint(self):
        # Test checks that api returns valid values
        self.list_test('/api/v1/project/', 1)
        self.details_test(
            ["project", self.initial_project.id],
            name=self.initial_project.name
        )
        # Try to create new projects and check list endpoint
        test_data = [
            {"name": f"TestProject{i}"}
            for i in range(2)
        ]
        id_list = self.mass_create("/api/v1/project/", test_data, 'name')
        self.list_test('/api/v1/project/', 1 + len(id_list))

Этот пример демонстрирует функциональность стандартного тест-кейс класса. Проекты по умолчанию инициализируются для получения наиболее быстрого и эффективного результата. Рекомендуется разбивать тесты на разные сущности в разные классы. В данном примере показан классический подход к тестированию, однако вы можете использовать bulk-запросы в ваших тестах.

Bulk-запросы в тестах

Система bulk-запросов хорошо подходит для тестирования и запуска валидных запросов. Предыдущий пример может быть переписан так:

from vstutils.tests import BaseTestCase


class ProjectTestCase(BaseTestCase):
    def setUp(self):
        super(ProjectTestCase, self).setUp()
        # init demo project
        self.initial_project = self.get_model_class('project.Test').objects.create(name="Test")

    def tearDown(self)
        super(ProjectTestCase, self).tearDown()
        # remove it after test
        self.initial_project.delete()

    def test_project_endpoint(self):
        test_data = [
            {"name": f"TestProject{i}"}
            for i in range(2)
        ]
        bulk_data = [
            {"method": "get", "path": ["project"]},
            {"method": "get", "path": ["project", self.initial_project.id]}
        ]
        bulk_data += [
            {"method": "post", "path": ["project"], "data": i}
            for i in test_data
        ]
        bulk_data.append(
            {"method": "get", "path": ["project"]}
        )
        results = self.bulk_transactional(bulk_data)

        self.assertEqual(results[0]['status'], 200)
        self.assertEqual(results[0]['data']['count'], 1)
        self.assertEqual(results[1]['status'], 200)
        self.assertEqual(results[1]['data']['name'], self.initial_project.name)

        for pos, result in enumerate(results[2:-1]):
            self.assertEqual(result['status'], 201)
            self.assertEqual(result['data']['name'], test_data[pos]['name'])

        self.assertEqual(results[-1]['status'], 200)
        self.assertEqual(results[-1]['data']['count'], 1 + len(test_data))

В этом случае хотя мы и получили больше кода, однако тесты стали ближе к процессу использования приложения в графическом интерфейсе, потому что проекты vstutils используют /api/endpoint/ для выполнения запросов. Так или иначе, bulk-запросы выполняются заметно быстрее благодаря оптимизации, которую они выполняют под капотом. Время выполнения теста, в котором используется bulk меньше по сравнению с тестом, использующим стандартный механизм.

API тест-кейса

class vstutils.tests.BaseTestCase(methodName='runTest')[исходный код]

Основной тест-кейс класс расширяет django.test.TestCase.

assertCheckDict(first, second, msg=None)[исходный код]

Падает, если два поля в словаре не равны по определению оператора „==“. Проверяет первое поле на пустоту и на равенство со вторым полем

Параметры:
assertCount(iterable, count, msg=None)[исходный код]

Вызывает len() через iterable и проверяет равенство с count.

Параметры:
  • iterable (typing.Sized) – любой итерируемый объект, который может быть отправлен в len().

  • count (int) – ожидаемый результат.

  • msg (typing.Any) – сообщение об ошибке

assertRCode(resp, code=200, *additional_info)[исходный код]

Падает, если коды ответа не совпадают. Сообщением явялется тело ответа.

Параметры:
bulk(data, code=200, **kwargs)[исходный код]

Делает нетранзакционный bulk-запрос и проверяет код состояния (200 по умолчанию)

Параметры:
Тип результата:

typing.Union[typing.List[typing.Dict[str, typing.Any]], str, bytes, bytearray, typing.Dict, typing.Sequence[typing.Union[typing.List[typing.Dict[str, typing.Any]], str, bytes, bytearray]]]

Результат:

bulk-ответ

bulk_transactional(data, code=200, **kwargs)[исходный код]

Делает транзакционный bulk-запрос и проверяет код состояния (200 по умолчанию)

Параметры:
Тип результата:

typing.Union[typing.List[typing.Dict[str, typing.Any]], str, bytes, bytearray, typing.Dict, typing.Sequence[typing.Union[typing.List[typing.Dict[str, typing.Any]], str, bytes, bytearray]]]

Результат:

bulk-ответ

call_registration(data, **kwargs)[исходный код]

Функция для вызова регистрации. Просто передайте данные формы вместе с заголовками.

Параметры:
  • data (dict) – Данные регистрации с формы.

  • kwargs – именованные аргументы вместе с заголовками запроса.

details_test(url, **kwargs)[исходный код]

Тест на получение детальной записи модели. При задании дополнительных именованных аргументов метод проверит их на равенство с полученными данными. Использует метод get_result().

Параметры:
  • url – url детальной записи. Например: /api/v1/project/1/ (где 1 - это уникальный идентификатор проекта). Вы можете использовать get_url() для построения url.

  • kwargs – параметры для проверки (ключ - имя поля, значение - значение поля).

endpoint_call(data=None, method='get', code=200, **kwargs)[исходный код]

Делает запрос на endpoint и проверяет код состояния ответа, если он задан (200 по умолчанию). Использует get_result().

Параметры:
Тип результата:

typing.Union[typing.List[typing.Dict[str, typing.Any]], str, bytes, bytearray, typing.Dict, typing.Sequence[typing.Union[typing.List[typing.Dict[str, typing.Any]], str, bytes, bytearray]]]

Результат:

bulk-ответ

endpoint_schema(**kwargs)[исходный код]

Делает запрос на схему. Возвращает словарь с данными swagger.

Параметры:

version – Версия API для парсера схемы.

get_count(model, **kwargs)[исходный код]

Простая обертка над get_model_filter(), возвращающая счетчик объектов.

Параметры:
Результат:

количество объектов в базе данных.

Тип результата:

int

get_model_class(model)[исходный код]

Получение класса модели по строке или получение аргумента модели.

Параметры:

model (str,django.db.models.Model) – строка, содержащая имя модели (если атрибут model установлен в класс тест-кейса), импорт модуля, app.ModelName или django.db.models.Model.

Результат:

Класс модели.

Тип результата:

django.db.models.Model

get_model_filter(model, **kwargs)[исходный код]

Простая обертка над get_model_class(), возвращающая фильтрованный queryset из модели.

Параметры:
Тип результата:

django.db.models.query.QuerySet

get_result(rtype, url, code=None, *args, **kwargs)[исходный код]

Запускает и проверяет код ответа для запроса, возвращает распарсенный результат запроса. Данный метод действует следующим образом:

  • Тестирует авторизацию клиента (вместе с user, который создается в setUp()).

  • Выполняет запрос (отправляет аргументы и именованные аргументы в метод запроса).

  • Парсит результат (конвертирует строку json в объект python).

  • Проверяет http-код состояния с помощью assertRCode() (если вы его не указали, будет выбран соответствующий код для выполняемого метода из стандартного набора std_codes).

  • Деавторизация пользователя.

  • Возвращение распарсенного результата.

Параметры:
  • rtype – тип запроса (методы из Client cls): get, post и т.д.

  • url – запрошенный url в виде строки или кортежа для get_url(). Вы можете использовать get_url() для построения url или задать его полной строкой.

  • code (int) – ожидаемый код возврата из запроса.

  • relogin – выполнение авторизации и деавторизации перед каждым вызовом. По умолчанию True.

  • args – дополнительные аргументы для метода запроса класса Client.

  • kwargs – дополнительные именованные аргументы для метода запроса класса Client.

Тип результата:

typing.Union[typing.List[typing.Dict[str, typing.Any]], str, bytes, bytearray, typing.Dict, typing.Sequence[typing.Union[typing.List[typing.Dict[str, typing.Any]], str, bytes, bytearray]]]

Результат:

результат запроса.

get_url(*items)[исходный код]

Функция для создания пути url, основанного на настройках VST_API_URL и VST_API_VERSION. Без аргументов возвращает путь к версии api по умолчанию.

Тип результата:

str

Результат:

строка вида /api/v1/.../.../ где ... - аргументы функции.

list_test(url, count)[исходный код]

Тест на получение списка моделей. Проверяет только количество записей. Использует метод get_result().

Параметры:
  • url – url абстрактного слоя. Например: /api/v1/project/. Вы можете использовать get_url() для построения url.

  • count – количество объектов в базе данных.

models = None

Атрибут с модулем моделей проекта по умолчанию.

classmethod patch(*args, **kwargs)[исходный код]

Простая обертка над unittest.mock.patch().

Тип результата:

typing.ContextManager[unittest.mock.Mock]

classmethod patch_field_default(model, field_name, value)[исходный код]

Этот метод помогает найти значение по умолчанию в поле модели. Он очень полезен для полезен для полей DateTime, где по умолчанию установлено django.utils.timezone.now().

Параметры:
  • model (django.db.models.base.Model) –

  • field_name (str) –

  • value (typing.Any) –

Тип результата:

typing.ContextManager[unittest.mock.Mock]

random_name()[исходный код]

Простая функция, возвращающая строку uuid1.

Тип результата:

str

std_codes: typing.Dict[str, int] = {'delete': 204, 'get': 200, 'patch': 200, 'post': 201}

Стандартный http-код для различных http-методов. Использует get_result()

class user_as(testcase, user)[исходный код]

Контекст для выполнения bulk или чего-либо еще от некоторого пользователя. Контекстный менеджер переопределяет self.user в TestCase’е и возвращает изменения после выхода из него.

Параметры:

user (django.contrib.auth.models.AbstractUser) – новый объект пользователя, от которого будет выполнение.

Утилиты

Здесь представлен проверенный набор утилит для разработки. Они включают в себя код, который так или иначе будет полезен по мере разработки. Vstutils использует большинство из этих функций под капотом.

class vstutils.utils.BaseEnum(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[исходный код]

BaseEnum расширяет класс Enum и используется для создания enum-подобных объектов, которые могут использоваться django-сериализаторами или django-моделями.

Пример:

from vstutils.models import BModel

class ItemCLasses(BaseEnum):
    FIRST = BaseEnum.SAME
    SECOND = BaseEnum.SAME
    THIRD = BaseEnum.SAME


class MyDjangoModel(BModel):
    item_class = models.CharField(max_length=ItemCLasses.max_len, choices=ItemCLasses.to_choices())

    @property
    def is_second(self):
        # Function check is item has second class of instance
        return ItemCLasses.SECOND.is_equal(self.item_class)

Примечание

вы можете установить значение как BaseEnum.LOWER` или ``BaseEnum.UPPER. Однако в обычных случаях рекомендуется использовать BaseEnum.SAME для оптимизации памяти.

class vstutils.utils.BaseVstObject[исходный код]

Стандартная миксина для пользовательских объектов, которым нужны настройки или кэш.

classmethod get_django_settings(name, default=None)[исходный код]

Получить параметры из настроек Django.

Параметры:
  • name (str) – название параметра

  • default (object) – значение параметра по умолчанию

Результат:

Параметр из настроек Django.

class vstutils.utils.Dict[исходный код]

Обертка над dict, возвращающая JSON при преобразовании в строку.

class vstutils.utils.Executor(stdout=-1, stderr=-2, **environ_variables)[исходный код]

Исполнитель команд с выводом и обработкой строк в реальном времени. По умолчанию и замыслу исполнитель инициализирует строковый атрибут output, который будет изменен оператором += с новыми строками с помощью метода Executor.write_output(). Переопределите метод, если нужно изменить поведение.

Класс исполнителя поддерживает периодеческий (0.01 сек) процесс обработки и выполняет некоторые проверки путем переопределения метода Executor.working_handler(). Если вы хотите отключить это поведение, переопределите метод значением None или используйте UnhandledExecutor.

Параметры:

environ_variables (str) –

exception CalledProcessError(returncode, cmd, output=None, stderr=None)

Выбрасывается, когда run() вызывается вместе с check=True и процесс возвращает код возврата отличный от нуля.

Атрибуты:

cmd, returncode, stdout, stderr, output

property stdout

Псевдоним для выходного атрибута, чтобы соответствовать stderr

async aexecute(cmd, cwd, env=None)[исходный код]

Выполняет команды и выводит их результат. Асинхронная реализация.

Параметры:
  • cmd – – список cmd-команд и аргументов

  • cwd – – рабочая директория

  • env – – дополнительные переменные окружения, которые перезаписывают переменные по умолчанию

Результат:

– строка, содержащая полный вывод

execute(cmd, cwd, env=None)[исходный код]

Выполняет команды и выводит их результат.

Параметры:
  • cmd – – список cmd-команд и аргументов

  • cwd – – рабочая директория

  • env – – дополнительные переменные окружения, которые перезаписывают переменные по умолчанию

Результат:

– строка, содержащая полный вывод

async post_execute(cmd, cwd, env, return_code)[исходный код]

Запускается после завершения выполнения.

Параметры:
  • cmd – – список cmd-команд и аргументов

  • cwd – – рабочая директория

  • env – – дополнительные переменные окружения, которые перезаписывают переменные по умолчанию

  • return_code – – код возврата выполненного процесса

async pre_execute(cmd, cwd, env)[исходный код]

Запускатеся перед началом выполнения.

Параметры:
  • cmd – – список cmd-команд и аргументов

  • cwd – – рабочая директория

  • env – – дополнительные переменные окружения, которые перезаписывают переменные по умолчанию

async working_handler(proc)[исходный код]

Дополнительный обработчик для запусков.

Параметры:

proc (asyncio.subprocess.Process) – запущенный процесс

write_output(line)[исходный код]
Параметры:

line (str) – – строка вывода команды

Результат:

None

Тип результата:

None

class vstutils.utils.KVExchanger(key, timeout=None)[исходный код]

Класс для передачи данных с использованием быстрого (кэш-подобного) хранилища между сервисами. Использует тот же самый кэш-бэкенд, что и Lock.

class vstutils.utils.Lock(id, payload=1, repeat=1, err_msg='', timeout=None)[исходный код]

Класс Lock предназначен для работы с несколькими задачами. Основан на KVExchanger. Lock позволяет только одному потоку войти в заблокированную и совместно используемую часть между приложениями, использующими один кэш блокировок (см. также [locks]).

Параметры:
  • id (int,str) – – уникальный id блокировки.

  • payload – – дополнительная информация о блокировке. Должна быть значением, равным True при приведении к булевому типу.

  • repeat (int) – – время ожидания lock.release. По умолчанию 1 секунда.

  • err_msg (str) – – сообщение для ошибки AcquireLockException.

Примечание

  • Использует django.core.cache и настройки в settings.py

  • Имеет Lock.SCHEDULER и Lock.GLOBAL id

Пример:
from vstutils.utils import Lock

with Lock("some_lock_identifier", repeat=30, err_msg="Locked by another proccess") as lock:
    # where
    # ``"some_lock_identifier"`` is unique id for lock and
    # ``30`` seconds lock is going wait until another process will release lock id.
    # After 30 sec waiting lock will raised with :class:`.Lock.AcquireLockException`
    # and ``err_msg`` value as text.
    some_code_execution()
    # ``lock`` object will has been automatically released after
    # exiting from context.
Другой пример без использования контекстного менеджера:
from vstutils.utils import Lock

# locked block after locked object created
lock = Lock("some_lock_identifier", repeat=30, err_msg="Locked by another proccess")
# deleting of object calls ``lock.release()`` which release and remove lock from id.
del lock
exception AcquireLockException[исходный код]

Исключение, которое будет выброшено в случае неосвобождения блокировки.

class vstutils.utils.ModelHandlers(type_name, err_message=None)[исходный код]

Обработчики для некоторых моделей, таких как „INTEGRATIONS“ или „REPO_BACKENDS“. Основан на ObjectHandlers, но больше сосредоточен на работе с моделями. Все handler-бэкенды получают объект модели по первому аргументу.

Атрибуты:

Параметры:
  • objects (dict) – – словарь объектов, например {<name>: <backend_class>}

  • keys (list) – – имена поддерживаемых бэкендов

  • values (list) – – поддерживаемые классы бэкендов

  • type_name – Имя для бэкенда, наподобие ключа в словаре.

get_object(name, obj)[исходный код]
Параметры:
  • name – – строковое имя бэкенда

  • name – str

  • obj (django.db.models.Model) – – объект модели

Результат:

объект бэкенда

Тип результата:

object

class vstutils.utils.ObjectHandlers(type_name, err_message=None)[исходный код]

Обертка обработчиков для получения объектов из некоторой структуры настроек.

Пример:
from vstutils.utils import ObjectHandlers

'''
In `settings.py` you should write some structure:

SOME_HANDLERS = {
    "one": {
        "BACKEND": "full.python.path.to.module.SomeClass"
    },
    "two": {
        "BACKEND": "full.python.path.to.module.SomeAnotherClass",
        "OPTIONS": {
            "some_named_arg": "value"
        }
    }
}
'''

handlers = ObjectHandlers('SOME_HANDLERS')

# Get class handler for 'one'
one_backend_class = handlers['one']
# Get object of backend 'two'
two_obj = handlers.get_object()
# Get object of backend 'two' with overriding constructor named arg
two_obj_overrided = handlers.get_object(some_named_arg='another_value')
Параметры:

type_name (str) – Имя для бэкенда, наподобие ключа в словаре.

backend(name)[исходный код]

Получить класс бэкенда

Параметры:

name (str) – – имя типа бэкенда

Результат:

класс бэкенда

Тип результата:

type,types.ModuleType,object

class vstutils.utils.Paginator(qs, chunk_size=None)[исходный код]

Класс для разбиения запроса на небольшие запросы.

class vstutils.utils.SecurePickling(secure_key=None)[исходный код]

Защищенная pickle-обертка с использованием шифра Виженера.

Предупреждение

В любом случае не используйте его с ненадежным средством передачи.

Пример:
from vstutils.utils import SecurePickling


serializer = SecurePickling('password')

# Init secret object
a = {"key": "value"}
# Serialize object with secret key
pickled = serializer.dumps(a)
# Deserialize object
unpickled = serializer.loads(pickled)

# Check, that object is correct
assert a == unpickled
class vstutils.utils.URLHandlers(type_name='URLS', *args, **kwargs)[исходный код]

Обработчик объекта для views в графическом интерфейсе. Использует GUI_VIEWS из settings.py. Основан на ObjectHandlers, но больше сосредоточен на urlpatterns.

Пример:
from vstutils.utils import URLHandlers


# By default gets from `GUI_VIEWS` in `settings.py`
urlpatterns = list(URLHandlers())
Параметры:

type_name – Имя для бэкенда, наподобие ключа в словаре.

get_object(name, *argv, **kwargs)[исходный код]

Получить объект кортежа url’ов для urls.py

Параметры:
  • name (str) – регулярное выражение url’а

  • argv – переопределенные аргументы

  • kwargs – переопределенные kwarg’и

Результат:

объект url’а

Тип результата:

django.urls.re_path

class vstutils.utils.UnhandledExecutor(stdout=-1, stderr=-2, **environ_variables)[исходный код]

Класс, основанный на Executor, но с выключенным working_handler.

Параметры:

environ_variables (str) –

class vstutils.utils.apply_decorators(*decorators)[исходный код]

Декоратор, оборачивающий метод или класс в список декораторов.

Пример:
from vstutils.utils import apply_decorators

def decorator_one(func):
    print(f"Decorated {func.__name__} by first decorator.")
    return func

def decorator_two(func):
    print(f"Decorated {func.__name__} by second decorator.")
    return func

@apply_decorators(decorator_one, decorator_two)
def decorated_function():
    # Function decorated by both decorators.
    print("Function call.")
class vstutils.utils.classproperty(fget, fset=None)[исходный код]

Декоратор, который из метода класса делает классовый property.

Пример:
from vstutils.utils import classproperty

class SomeClass(metaclass=classproperty.meta):
    # Metaclass is needed for set attrs in class
    # instead of and not only object.

    some_value = None

    @classproperty
    def value(cls):
        return cls.some_value

    @value.setter
    def value(cls, new_value):
        cls.some_value = new_value
Параметры:
  • fget – Функция для получения значения атрибута.

  • fset – Функция для установки значения атрибута.

vstutils.utils.create_view(model, **meta_options)[исходный код]

Простая функция для получения сгенерированного view стандартными средствами, но с перегруженными мета-параметрами. Этот метод позволяет полностью отказаться от создания прокси-моделей.

Пример:
from vstutils.utils import create_view

from .models import Host

# Host model has full :class:`vstutils.api.base.ModelViewSet` view.
# For overriding and create simple list view just setup this:
HostListViewSet = create_view(
    HostList,
    view_class='list_only'
)

Примечание

Данный метод также рекомендуется применять в случаях, когда имеются проблемы с рекурсивными импортами.

Параметры:

model (Type[vstutils.models.BaseModel]) – Класс модели с методом .get_view_class. Этот метод также имеет vstutils.models.BModel.

Тип результата:

vstutils.api.base.GenericViewSet

vstutils.utils.decode(key, enc)[исходный код]

Декодировать строку из закодированной шифром Виженера.

Параметры:
  • key (str) – – секретный ключ для кодирования

  • enc (str) – – закодированная строка для декодирования

Результат:

– декодированная строка

Тип результата:

str

vstutils.utils.deprecated(func)[исходный код]

Данный декоратор может быть использован, чтобы пометить функцию как устаревшую. После этого ее вызов приведет к выдаче соответствующего предупреждения.

Параметры:

func – любой вызываемый объект, который будет обернут и выдаст предупреждение об устаревании при вызове.

vstutils.utils.encode(key, clear)[исходный код]

Закодировать строку шифром Виженера.

Параметры:
  • key (str) – – секретный ключ для кодирования

  • clear (str) – – чистое значение для кодирования

Результат:

– закодированная строка

Тип результата:

str

vstutils.utils.get_render(name, data, trans='en')[исходный код]

Рендеринг строки из шаблона.

Параметры:
  • name (str) – – полное название шаблона

  • data (dict) – – словарь переменных для рендеринга

  • trans (str) – – перевод для рендера. По умолчанию „en“.

Результат:

– отрендеренная строка

Тип результата:

str

vstutils.utils.lazy_translate(text)[исходный код]

Функция lazy_translate имеет то же поведение, что и translate(), но оборачивает его в lazy promise.

Это полезно, например, для перевода сообщений об ошибках в атрибутах класса, когда целевой язык еще неизвестен.

Параметры:

text – Текстовое сообщение, которое должно быть переведено.

vstutils.utils.list_to_choices(items_list, response_type=<class 'list'>)[исходный код]

Метод, предназначенный для создания django-модели choices из плоского списка значений.

Параметры:
  • items_list – плоский список значений.

  • response_type – тип приведения возвращаемого сопоставления

Результат:

список кортежей из значений items_list

class vstutils.utils.model_lock_decorator(**kwargs)[исходный код]

Декоратор для функций, где kwarg „pk“ существует для блокировки по id.

Предупреждение

  • В случае ошибки блокировки выбрасывает Lock.AcquireLockException

  • Метод должен иметь и быть вызван вместе с именованным аргументом pk.

class vstutils.utils.raise_context(*args, **kwargs)[исходный код]

Контекст для игнорирования исключений.

class vstutils.utils.raise_context_decorator_with_default(*args, **kwargs)[исходный код]

Контекст для предотвращения исключений и возврата значения по умолчанию.

Пример:
from yaml import load
from vstutils.utils import raise_context_decorator_with_default


@raise_context_decorator_with_default(default={})
def get_host_data(yaml_path, host):
    with open(yaml_path, 'r') as fd:
        data = load(fd.read(), Loader=Loader)
    return data[host]
    # This decorator used when you must return some value even on error
    # In log you also can see traceback for error if it occur

def clone_host_data(host):
    bs_data = get_host_data('inventories/aws/hosts.yml', 'build_server')
    ...
class vstutils.utils.redirect_stdany(new_stream=<_io.StringIO object>, streams=None)[исходный код]

Контекст для перенаправления любого вывода в свой поток.

Примечание

  • В контексте возвращает объект потока.

  • При выходе возвращает старые потоки.

vstutils.utils.send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None, html_message=None, **kwargs)[исходный код]

Обертка над django.core.mail.send_mail(), предоставляющая дополнительные именованные аргументы.

vstutils.utils.send_template_email(sync=False, **kwargs)[исходный код]

Функция, выполняющая синхронную или асинхронную отправку электронной почты в зависимости от аргумента sync и переменной настроек «RPC_ENABLED». Вы можете использовать эту функцию для отправки сообщений, она отправляет сообщение асинхронно или синхронно. Если вы не установили настройки для Celery или не установили Celery, она отправляет письмо синхронно. Если установлен и настроен Celery, и аргумент sync функции установлен на False, она отправляет электронное письмо асинхронно.

Параметры:
  • sync – аргумент для определения, как отправлять электронную почту, асинхронно или синхронно.

  • subject – тема письма.

  • email – список строк или отдельная строка с адресами электронной почты получателей.

  • template_name – относительный путь к шаблону в директории templates, должен включать расширение имени файла.

  • context_data – словарь с контекстом для отображения шаблона сообщения.

vstutils.utils.send_template_email_handler(subject, email_from, email, template_name, context_data=None, **kwargs)[исходный код]

Функция для отправки электронной почты. Функция преобразует получателя в список и устанавливает контекст перед отправкой, если это возможно.

Параметры:
  • subject – тема письма.

  • email_from – адрес отправителя, который будет указан в письме.

  • email – список строк или отдельная строка с адресами электронной почты получателей.

  • template_name – относительный путь к шаблону в директории templates, должен включать расширение имени файла.

  • context_data – словарь с контекстом для отображения шаблона сообщения.

  • kwargs – дополнительные именованные аргументы для send_mail.

Результат:

Количество отправленных электронных писем.

class vstutils.utils.tmp_file(data='', mode='w', bufsize=-1, **kwargs)[исходный код]

Временный файл с сгенерированным и автоматически именем и удаленный по закрытии

Атрибуты:

Параметры:
  • data (str) – – строка для записи во временный файл.

  • mode (str) – – режим открытия файла. По умолчанию w.

  • bufsize (int) – – размер буфера для tempfile.NamedTemporaryFile.

  • kwargs – – другие именованные аргументы для tempfile.NamedTemporaryFile.

write(wr_string)[исходный код]

Записать в файл и очистить буфер

Параметры:

wr_string (str) – – записываемая строка

Результат:

None

Тип результата:

None

class vstutils.utils.tmp_file_context(*args, **kwargs)[исходный код]

Объект контекста для работы с tmp_file. Автоматическое закрывается при выходе из контекста и удаляется файл, если он все еще существует.

Данный менеджер контекста работает с class:.tmp_file

vstutils.utils.translate(text)[исходный код]

Функция translate поддерживает динамический перевод сообщения с использованием стандартных механизмов i18n в vstutils.

Использует функцию django.utils.translation.get_language() для получения кода языка и пытается получить перевод из списка доступных.

Параметры:

text – Текстовое сообщение, которое должно быть переведено.