garpix-utils


Namegarpix-utils JSON
Version 1.9.1 PyPI version JSON
download
home_pagehttps://github.com/garpixcms/garpix_utils
Summary
upload_time2023-11-07 15:52:00
maintainer
docs_urlNone
authorGarpix LTD
requires_python
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Garpix Utils

Набор утилит для GARPIX CMS.

Утилиты:

* `file.get_file_path` - генерация пути для сохранения файла (для FileField)
* `string.get_random_string` - создание строки случайных символов
* `signature.make_signature_sha512` - создание цифровой подписи
* `models.ActiveMixin` - миксин для моделей, которым необходимо поле "Активность"
* `models.EmptyMixin` - миксин-пустышка, который можно использовать при обязательных миксинах
* `models.AvailableMixin` - миксин для моделей, которые должны обладать полями "Активность" и "Удалено"
* `models.PolymorphicActiveMixin` - миксин для модели `garpix_page.BasePage`, добавляет возможность выбора доступных страниц (которые активны). Используется внутри GARPIX CMS.
* `templatetags.url_replace` - подмена одного значения в dict на другое в Django-шаблонах.
* `models.DeleteMixin` - миксин для моделей, добавляющий функционал мягкого/жесткого удаления, `models.AdminDeleteMixin` - миксин для админ.модели.
* `models.PolymorphicAvailableMixin` - миксин для модели `garpix_page.BasePage`, добавляет возможность выбора доступных страниц (которые активны и неудалены). Используется внутри GARPIX CMS.
* `models.GarpixSiteConfiguration` - класс для добавления мультисайтовых настроек в проекте, `admin.GarpixSiteConfigurationAdmin` - класс для админ.панели


## Установка

Установка с помощью pip:

```bash
pip install garpix_utils
```

### Утилиты

#### `file.get_file_path` - генерация пути для сохранения файла (для FileField)
#### `file.get_secret_path` - генерация уникального пути для переданного имени файла

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

Можно использовать в качестве значения 'upload_to' поля FileField модели Django. 

ПРИМЕР:

```
from garpix_utils.file import get_file_path
from django.db import models


class FileModel(models.Model):
    # ...
    file = models.FileField(upload_to=get_file_path, blank=True, null=True, verbose_name=_('File'))
    # ...
```


#### `string.get_random_string` - создание строки случайных символов

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

Параметры:

* size: int - количество символов. По умолчанию - 8.
* chars: str - строка из списка символов, которые могут быть в строке. По умолчанию `string.ascii_uppercase + string.digits`.

ПРИМЕР:

Пример 1

```
from garpix_utils.string import get_random_string

random_string = get_random_string(16)

# random_string = '451DNCLZLY2HDDDX'
```

Пример 2

```
import string
from garpix_utils.string import get_random_string

random_string = get_random_string(8, string.ascii_lowercase)

# random_string = 'palsjpyz'
```

Пример 3

```
from garpix_utils.string import get_random_string

random_string = get_random_string(16, '01')

# random_string = '0110111101010100'
```

#### `signature.make_signature_sha512` - создание цифровой подписи

Создает сигнатуру (цифровую подпись) по указанным параметрам с хэшированием SHA-512.

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

ВНИМАНИЕ! Если необходим другой алгоритм шифрования, то загляните в эту функцию, можно сделать свой по аналогии.

Параметры:

* params: dict - словарь параметров. Если присутствует signature_key, то он будет удален.
* signature_key: str - ключ параметра с сигнатурой. По умолчанию "sig".
* secret: str - секретный ключ, который будет приконкатенирован в конце перед хэшированием.

Алгоритм:

1. Берет словарь параметров, удаляет оттуда параметр с ключом сигнатуры (см. переменную signature_key, по умолчанию значение "sig")
2. Получившийся словарь сортирует по названию ключа в алфавитном порядке. Все вложенные данные тоже сортируются по ключу, списочные - просто по алфавиту.
3. Последовательно конкатенирует ключ со значением в единую строку.
4. В конце конкатенирует значение переменной secret (по умолчанию равна "secret").
5. Хэширует по алгоритму SHA-512 и возвращает строку в нижнем регистре.
6. Возвращает получившийся результат.

ПРИМЕР:

```python
# необходимый вам файл

from garpix_utils.signature import make_signature_sha512


sig = make_signature_sha512({'a': 'xxx', 'c': 'ggg', 'b': '111', 'sig': '123', 'd': [3, 1, 2], 'e': {'b': '2', 'a': '1'}}, signature_key='sig', secret='secret')

# sig = '2123086085ec1fe67595d7b3d2b6a0dbf3f33e528d78366b8d62d7f0a7e3c090077b0f7b8dc84921a6087aa57b8284bd1e74702df7a16e96f73f627e6eea815a'
```

Разбор примера по шагам:

**Шаг 1**

* Было: {'a': 'xxx', 'c': 'ggg', 'b': '111', 'sig': '123', 'd': [3, 1, 2], 'e': {'b': '2', 'a': '1'}}
* Стало: {'a': 'xxx', 'c': 'ggg', 'b': '111', 'd': [3, 1, 2], 'e': {'b': '2', 'a': '1'}}

**Шаг 2**

* Было: {'a': 'xxx', 'c': 'ggg', 'b': '111', 'd': [3, 1, 2], 'e': {'b': '2', 'a': '1'}}
* Стало: {'a': 'xxx', 'b': '111', 'c': 'ggg', 'd': [1, 2, 3], 'e': {'a': '1', 'b': '2'}}

**Шаг 3**

* Было: {'a': 'xxx', 'b': '111', 'c': 'ggg', 'd': [1, 2, 3], 'e': {'a': '1', 'b': '2'}}
* Стало: 'axxxb111cgggd123ea1b2'

**Шаг 4**

* Было: 'axxxb111cgggd123ea1b2'
* Стало: 'axxxb111cgggd123ea1b2secret'

**Шаг 5**

* Было: 'axxxb111cgggd123ea1b2secret'
* Стало: '2123086085ec1fe67595d7b3d2b6a0dbf3f33e528d78366b8d62d7f0a7e3c090077b0f7b8dc84921a6087aa57b8284bd1e74702df7a16e96f73f627e6eea815a'

#### `models.ActiveMixin` - миксин для моделей, которым необходимо поле "Активность"

Добавляет поле `is_active (Boolean, default=True)`. Добавляет менеджера `active_objects`, который выбирает только активные объекты (`is_active=True`).

ПРИМЕР:

```python
# необходимый вам файл

from django.db import models
from garpix_utils.models import ActiveMixin


class Product(ActiveMixin, models.Model):
    pass


Product.active_objects.all()

# Будут выбраны записи только с is_active == True.
```

#### `models.EmptyMixin` - миксин-пустышка, который можно использовать при обязательных миксинах

ПРИМЕР:

```python
# необходимый вам файл

from django.db import models
from garpix_utils.models import EmptyMixin


class Product(EmptyMixin, models.Model):
    pass

# Ничего не изменилось.
```

Или использование в пакете `garpix_blog`:

```python
# app/settings.py

GARPIX_BLOG_MIXIN = 'garpix_utils.models.EmptyMixin'

```

#### `models.AvailableMixin` - миксин для моделей, которые должны обладать полями "Активность" и "Удалено"

Добавляет поля `is_active (Boolean, default=True)` и `is_deleted (Boolean, default=False)`. Добавляет менеджера `available_objects`, который выбирает только доступные объекты (`is_active=True, is_deleted=False`).

ПРИМЕР:

```python
# необходимый вам файл

from django.db import models
from garpix_utils.models import AvailableMixin


class Product(AvailableMixin, models.Model):
    pass


Product.available_objects.all()

# Будут выбраны записи только с is_active == True.
```

#### `templatetags.url_replace` - подмена одного значения в dict на другое в Django-шаблонах.

ПРИМЕР для пагинации (взято из https://github.com/garpixcms/garpix_page/):

```
{% load url_replace %}

<nav>
    <ul class="pagination">
        {% for page_num in page_range %}
            <li class="page-item {% if page_num == page %}active{% endif %}">
                <a class="page-link" href="?{% url_replace request 'page' page_num %}">{{ page_num }}</a>
            </li>
        {% endfor %}
    </ul>
</nav>
```

# Changelog

See [CHANGELOG.md](CHANGELOG.md).

# Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md).

# License

[MIT](LICENSE)

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/garpixcms/garpix_utils",
    "name": "garpix-utils",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "",
    "author": "Garpix LTD",
    "author_email": "info@garpix.com",
    "download_url": "https://files.pythonhosted.org/packages/ac/bb/8cbcdf16201b9b3118dc135252df45f2a927ede1d3115bec4932da519c06/garpix_utils-1.9.1.tar.gz",
    "platform": null,
    "description": "# Garpix Utils\n\n\u041d\u0430\u0431\u043e\u0440 \u0443\u0442\u0438\u043b\u0438\u0442 \u0434\u043b\u044f GARPIX CMS.\n\n\u0423\u0442\u0438\u043b\u0438\u0442\u044b:\n\n* `file.get_file_path` - \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0443\u0442\u0438 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430 (\u0434\u043b\u044f FileField)\n* `string.get_random_string` - \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432\n* `signature.make_signature_sha512` - \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0439 \u043f\u043e\u0434\u043f\u0438\u0441\u0438\n* `models.ActiveMixin` - \u043c\u0438\u043a\u0441\u0438\u043d \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u043b\u0435 \"\u0410\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c\"\n* `models.EmptyMixin` - \u043c\u0438\u043a\u0441\u0438\u043d-\u043f\u0443\u0441\u0442\u044b\u0448\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043c\u0438\u043a\u0441\u0438\u043d\u0430\u0445\n* `models.AvailableMixin` - \u043c\u0438\u043a\u0441\u0438\u043d \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u043b\u0430\u0434\u0430\u0442\u044c \u043f\u043e\u043b\u044f\u043c\u0438 \"\u0410\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c\" \u0438 \"\u0423\u0434\u0430\u043b\u0435\u043d\u043e\"\n* `models.PolymorphicActiveMixin` - \u043c\u0438\u043a\u0441\u0438\u043d \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0438 `garpix_page.BasePage`, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 (\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u044b). \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 GARPIX CMS.\n* `templatetags.url_replace` - \u043f\u043e\u0434\u043c\u0435\u043d\u0430 \u043e\u0434\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 dict \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0435 \u0432 Django-\u0448\u0430\u0431\u043b\u043e\u043d\u0430\u0445.\n* `models.DeleteMixin` - \u043c\u0438\u043a\u0441\u0438\u043d \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0435\u0439, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043c\u044f\u0433\u043a\u043e\u0433\u043e/\u0436\u0435\u0441\u0442\u043a\u043e\u0433\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f, `models.AdminDeleteMixin` - \u043c\u0438\u043a\u0441\u0438\u043d \u0434\u043b\u044f \u0430\u0434\u043c\u0438\u043d.\u043c\u043e\u0434\u0435\u043b\u0438.\n* `models.PolymorphicAvailableMixin` - \u043c\u0438\u043a\u0441\u0438\u043d \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0438 `garpix_page.BasePage`, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 (\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u044b \u0438 \u043d\u0435\u0443\u0434\u0430\u043b\u0435\u043d\u044b). \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 GARPIX CMS.\n* `models.GarpixSiteConfiguration` - \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0443\u043b\u044c\u0442\u0438\u0441\u0430\u0439\u0442\u043e\u0432\u044b\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435, `admin.GarpixSiteConfigurationAdmin` - \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0430\u0434\u043c\u0438\u043d.\u043f\u0430\u043d\u0435\u043b\u0438\n\n\n## \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430\n\n\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e pip:\n\n```bash\npip install garpix_utils\n```\n\n### \u0423\u0442\u0438\u043b\u0438\u0442\u044b\n\n#### `file.get_file_path` - \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0443\u0442\u0438 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430 (\u0434\u043b\u044f FileField)\n#### `file.get_secret_path` - \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0443\u0442\u0438 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0438\u043c\u0435\u043d\u0438 \u0444\u0430\u0439\u043b\u0430\n\n\u0424\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043f\u0443\u0442\u044c \u0444\u0430\u0439\u043b\u0430 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0433\u043e\u0434\u0430 \u0438 \u043c\u0435\u0441\u044f\u0446\u0430, \u0447\u0442\u043e\u0431\u044b \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0444\u0430\u0439\u043b\u043e\u0432 \u043d\u0435 \u0441\u043a\u0430\u043f\u043b\u0438\u0432\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435.\n\n\u041c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f 'upload_to' \u043f\u043e\u043b\u044f FileField \u043c\u043e\u0434\u0435\u043b\u0438 Django. \n\n\u041f\u0420\u0418\u041c\u0415\u0420:\n\n```\nfrom garpix_utils.file import get_file_path\nfrom django.db import models\n\n\nclass FileModel(models.Model):\n    # ...\n    file = models.FileField(upload_to=get_file_path, blank=True, null=True, verbose_name=_('File'))\n    # ...\n```\n\n\n#### `string.get_random_string` - \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432\n\n\u0421\u043e\u0437\u0434\u0430\u0435\u0442 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0438 \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c\u0438.\n\n\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b:\n\n* size: int - \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e - 8.\n* chars: str - \u0441\u0442\u0440\u043e\u043a\u0430 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0432 \u0441\u0442\u0440\u043e\u043a\u0435. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e `string.ascii_uppercase + string.digits`.\n\n\u041f\u0420\u0418\u041c\u0415\u0420:\n\n\u041f\u0440\u0438\u043c\u0435\u0440 1\n\n```\nfrom garpix_utils.string import get_random_string\n\nrandom_string = get_random_string(16)\n\n# random_string = '451DNCLZLY2HDDDX'\n```\n\n\u041f\u0440\u0438\u043c\u0435\u0440 2\n\n```\nimport string\nfrom garpix_utils.string import get_random_string\n\nrandom_string = get_random_string(8, string.ascii_lowercase)\n\n# random_string = 'palsjpyz'\n```\n\n\u041f\u0440\u0438\u043c\u0435\u0440 3\n\n```\nfrom garpix_utils.string import get_random_string\n\nrandom_string = get_random_string(16, '01')\n\n# random_string = '0110111101010100'\n```\n\n#### `signature.make_signature_sha512` - \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0439 \u043f\u043e\u0434\u043f\u0438\u0441\u0438\n\n\u0421\u043e\u0437\u0434\u0430\u0435\u0442 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0443 (\u0446\u0438\u0444\u0440\u043e\u0432\u0443\u044e \u043f\u043e\u0434\u043f\u0438\u0441\u044c) \u043f\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c \u0441 \u0445\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c SHA-512.\n\n\u041e\u0431\u044b\u0447\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u044d\u043a\u0432\u0430\u0439\u0440\u0438\u043d\u0433\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0437\u0430\u0449\u0438\u0442\u044b \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0439 \u043f\u043e\u0434\u043f\u0438\u0441\u044c\u044e.\n\n\u0412\u041d\u0418\u041c\u0410\u041d\u0418\u0415! \u0415\u0441\u043b\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0434\u0440\u0443\u0433\u043e\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0442\u043e \u0437\u0430\u0433\u043b\u044f\u043d\u0438\u0442\u0435 \u0432 \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438.\n\n\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b:\n\n* params: dict - \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432. \u0415\u0441\u043b\u0438 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 signature_key, \u0442\u043e \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d.\n* signature_key: str - \u043a\u043b\u044e\u0447 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0441 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u043e\u0439. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \"sig\".\n* secret: str - \u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043a\u043b\u044e\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043a\u043e\u043d\u043a\u0430\u0442\u0435\u043d\u0438\u0440\u043e\u0432\u0430\u043d \u0432 \u043a\u043e\u043d\u0446\u0435 \u043f\u0435\u0440\u0435\u0434 \u0445\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c.\n\n\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c:\n\n1. \u0411\u0435\u0440\u0435\u0442 \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u043e\u0442\u0442\u0443\u0434\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0441 \u043a\u043b\u044e\u0447\u043e\u043c \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u044b (\u0441\u043c. \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e signature_key, \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \"sig\")\n2. \u041f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u043f\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044e \u043a\u043b\u044e\u0447\u0430 \u0432 \u0430\u043b\u0444\u0430\u0432\u0438\u0442\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435. \u0412\u0441\u0435 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u043e\u0436\u0435 \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043f\u043e \u043a\u043b\u044e\u0447\u0443, \u0441\u043f\u0438\u0441\u043e\u0447\u043d\u044b\u0435 - \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e \u0430\u043b\u0444\u0430\u0432\u0438\u0442\u0443.\n3. \u041f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u043e\u043d\u043a\u0430\u0442\u0435\u043d\u0438\u0440\u0443\u0435\u0442 \u043a\u043b\u044e\u0447 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0432 \u0435\u0434\u0438\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443.\n4. \u0412 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u043a\u0430\u0442\u0435\u043d\u0438\u0440\u0443\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 secret (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0440\u0430\u0432\u043d\u0430 \"secret\").\n5. \u0425\u044d\u0448\u0438\u0440\u0443\u0435\u0442 \u043f\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0443 SHA-512 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 \u043d\u0438\u0436\u043d\u0435\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0435.\n6. \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.\n\n\u041f\u0420\u0418\u041c\u0415\u0420:\n\n```python\n# \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u0432\u0430\u043c \u0444\u0430\u0439\u043b\n\nfrom garpix_utils.signature import make_signature_sha512\n\n\nsig = make_signature_sha512({'a': 'xxx', 'c': 'ggg', 'b': '111', 'sig': '123', 'd': [3, 1, 2], 'e': {'b': '2', 'a': '1'}}, signature_key='sig', secret='secret')\n\n# sig = '2123086085ec1fe67595d7b3d2b6a0dbf3f33e528d78366b8d62d7f0a7e3c090077b0f7b8dc84921a6087aa57b8284bd1e74702df7a16e96f73f627e6eea815a'\n```\n\n\u0420\u0430\u0437\u0431\u043e\u0440 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u043e \u0448\u0430\u0433\u0430\u043c:\n\n**\u0428\u0430\u0433 1**\n\n* \u0411\u044b\u043b\u043e: {'a': 'xxx', 'c': 'ggg', 'b': '111', 'sig': '123', 'd': [3, 1, 2], 'e': {'b': '2', 'a': '1'}}\n* \u0421\u0442\u0430\u043b\u043e: {'a': 'xxx', 'c': 'ggg', 'b': '111', 'd': [3, 1, 2], 'e': {'b': '2', 'a': '1'}}\n\n**\u0428\u0430\u0433 2**\n\n* \u0411\u044b\u043b\u043e: {'a': 'xxx', 'c': 'ggg', 'b': '111', 'd': [3, 1, 2], 'e': {'b': '2', 'a': '1'}}\n* \u0421\u0442\u0430\u043b\u043e: {'a': 'xxx', 'b': '111', 'c': 'ggg', 'd': [1, 2, 3], 'e': {'a': '1', 'b': '2'}}\n\n**\u0428\u0430\u0433 3**\n\n* \u0411\u044b\u043b\u043e: {'a': 'xxx', 'b': '111', 'c': 'ggg', 'd': [1, 2, 3], 'e': {'a': '1', 'b': '2'}}\n* \u0421\u0442\u0430\u043b\u043e: 'axxxb111cgggd123ea1b2'\n\n**\u0428\u0430\u0433 4**\n\n* \u0411\u044b\u043b\u043e: 'axxxb111cgggd123ea1b2'\n* \u0421\u0442\u0430\u043b\u043e: 'axxxb111cgggd123ea1b2secret'\n\n**\u0428\u0430\u0433 5**\n\n* \u0411\u044b\u043b\u043e: 'axxxb111cgggd123ea1b2secret'\n* \u0421\u0442\u0430\u043b\u043e: '2123086085ec1fe67595d7b3d2b6a0dbf3f33e528d78366b8d62d7f0a7e3c090077b0f7b8dc84921a6087aa57b8284bd1e74702df7a16e96f73f627e6eea815a'\n\n#### `models.ActiveMixin` - \u043c\u0438\u043a\u0441\u0438\u043d \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u043b\u0435 \"\u0410\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c\"\n\n\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0435 `is_active (Boolean, default=True)`. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 `active_objects`, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b (`is_active=True`).\n\n\u041f\u0420\u0418\u041c\u0415\u0420:\n\n```python\n# \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u0432\u0430\u043c \u0444\u0430\u0439\u043b\n\nfrom django.db import models\nfrom garpix_utils.models import ActiveMixin\n\n\nclass Product(ActiveMixin, models.Model):\n    pass\n\n\nProduct.active_objects.all()\n\n# \u0411\u0443\u0434\u0443\u0442 \u0432\u044b\u0431\u0440\u0430\u043d\u044b \u0437\u0430\u043f\u0438\u0441\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 is_active == True.\n```\n\n#### `models.EmptyMixin` - \u043c\u0438\u043a\u0441\u0438\u043d-\u043f\u0443\u0441\u0442\u044b\u0448\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043c\u0438\u043a\u0441\u0438\u043d\u0430\u0445\n\n\u041f\u0420\u0418\u041c\u0415\u0420:\n\n```python\n# \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u0432\u0430\u043c \u0444\u0430\u0439\u043b\n\nfrom django.db import models\nfrom garpix_utils.models import EmptyMixin\n\n\nclass Product(EmptyMixin, models.Model):\n    pass\n\n# \u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c.\n```\n\n\u0418\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u043f\u0430\u043a\u0435\u0442\u0435 `garpix_blog`:\n\n```python\n# app/settings.py\n\nGARPIX_BLOG_MIXIN = 'garpix_utils.models.EmptyMixin'\n\n```\n\n#### `models.AvailableMixin` - \u043c\u0438\u043a\u0441\u0438\u043d \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u043b\u0430\u0434\u0430\u0442\u044c \u043f\u043e\u043b\u044f\u043c\u0438 \"\u0410\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c\" \u0438 \"\u0423\u0434\u0430\u043b\u0435\u043d\u043e\"\n\n\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u044f `is_active (Boolean, default=True)` \u0438 `is_deleted (Boolean, default=False)`. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 `available_objects`, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b (`is_active=True, is_deleted=False`).\n\n\u041f\u0420\u0418\u041c\u0415\u0420:\n\n```python\n# \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u0432\u0430\u043c \u0444\u0430\u0439\u043b\n\nfrom django.db import models\nfrom garpix_utils.models import AvailableMixin\n\n\nclass Product(AvailableMixin, models.Model):\n    pass\n\n\nProduct.available_objects.all()\n\n# \u0411\u0443\u0434\u0443\u0442 \u0432\u044b\u0431\u0440\u0430\u043d\u044b \u0437\u0430\u043f\u0438\u0441\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 is_active == True.\n```\n\n#### `templatetags.url_replace` - \u043f\u043e\u0434\u043c\u0435\u043d\u0430 \u043e\u0434\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 dict \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0435 \u0432 Django-\u0448\u0430\u0431\u043b\u043e\u043d\u0430\u0445.\n\n\u041f\u0420\u0418\u041c\u0415\u0420 \u0434\u043b\u044f \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0438 (\u0432\u0437\u044f\u0442\u043e \u0438\u0437 https://github.com/garpixcms/garpix_page/):\n\n```\n{% load url_replace %}\n\n<nav>\n    <ul class=\"pagination\">\n        {% for page_num in page_range %}\n            <li class=\"page-item {% if page_num == page %}active{% endif %}\">\n                <a class=\"page-link\" href=\"?{% url_replace request 'page' page_num %}\">{{ page_num }}</a>\n            </li>\n        {% endfor %}\n    </ul>\n</nav>\n```\n\n# Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md).\n\n# Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md).\n\n# License\n\n[MIT](LICENSE)\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "",
    "version": "1.9.1",
    "project_urls": {
        "Homepage": "https://github.com/garpixcms/garpix_utils"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2d85b6c4b80bdff0606af1c3d86ba072c3652c9e0b87122b50b4686842945b64",
                "md5": "8804833de1f7702b777812f35d021cb3",
                "sha256": "774a9428c1ac938505e2c1232990b69ab1e52008561dbbb86cb088920b95d998"
            },
            "downloads": -1,
            "filename": "garpix_utils-1.9.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8804833de1f7702b777812f35d021cb3",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 49723,
            "upload_time": "2023-11-07T15:51:58",
            "upload_time_iso_8601": "2023-11-07T15:51:58.660655Z",
            "url": "https://files.pythonhosted.org/packages/2d/85/b6c4b80bdff0606af1c3d86ba072c3652c9e0b87122b50b4686842945b64/garpix_utils-1.9.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "acbb8cbcdf16201b9b3118dc135252df45f2a927ede1d3115bec4932da519c06",
                "md5": "4bb67370334d906ae43e624bcff9168c",
                "sha256": "2fdd685e81e37b2228fff668ab887ca2ff0a464c54ed8780f5859bdffe474f58"
            },
            "downloads": -1,
            "filename": "garpix_utils-1.9.1.tar.gz",
            "has_sig": false,
            "md5_digest": "4bb67370334d906ae43e624bcff9168c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 26404,
            "upload_time": "2023-11-07T15:52:00",
            "upload_time_iso_8601": "2023-11-07T15:52:00.982912Z",
            "url": "https://files.pythonhosted.org/packages/ac/bb/8cbcdf16201b9b3118dc135252df45f2a927ede1d3115bec4932da519c06/garpix_utils-1.9.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-11-07 15:52:00",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "garpixcms",
    "github_project": "garpix_utils",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "garpix-utils"
}
        
Elapsed time: 0.24491s