django-sweet-utils


Namedjango-sweet-utils JSON
Version 1.5.0 PyPI version JSON
download
home_pagehttps://github.com/AllYouZombies/django-sweet-utils
SummaryA little django code sugar.
upload_time2023-06-15 06:48:15
maintainer
docs_urlNone
authorAstafeev Rustam
requires_python>=3.6
licenseMIT License
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Django sweet utils.

[![Downloads](https://static.pepy.tech/personalized-badge/django-sweet-utils?period=total&units=international_system&left_color=black&right_color=orange&left_text=Downloads)](https://pepy.tech/project/django-sweet-utils)
  
A little django code sugar.
  
> If you find this package useful, please star it on [GitHub](https://github.com/AllYouZombies/django-sweet-utils).
  
## Quickstart

1. Add `django_sweet_utils` to your `INSTALLED_APPS` setting like this:
    ```
    INSTALLED_APPS = [
        ...
        'django_sweet_utils',
        ...
    ]
    ```

2. Inherit your models from `django_sweet_utils.db.models.Model`:
   ```
   from django_sweet_utils.db.models import Model
   
   
   class MyModel(Model):
      ...
   ```
   
   From now your models has the following fields:
      - `uuid4` as object id;
      - `created_at` as object creation time;
      - `updated_at` as object last update time;
      - `is_deleted` as indicator that object is deleted or not;  
     
     
   Models that inherited from `django_sweet_utils.db.models.Model` can be filtered with simple `existing()` property:
   ```
   from django_sweet_utils.db.models import Model
   
   
   class MyModel(Model):
      ...
   
   
   queryset = MyModel.objects.existing()
   ```
   This returns queryset filtered by `is_deleted=False`

   Also, now you don't need to catch `DoesNotExist` error when attempting to get some object while it does not exist.
   Just use `get_or_none()` instead of `get()` and query returns `None` if there is no object.


## Features

### Models

#### Fake deletion

You can delete your objects without actual database deletion.
Just use `delete()` method on your model instance and it will be marked as deleted with `is_deleted=True`:

To perform actual deletion use `hard_delete()` method instead.

#### UUID4 as object id

Every model instance has `uuid4` field as object id.

#### Created and updated time

Every model instance has `created_at` and `updated_at` fields as object creation and last update time.

#### Existing objects

You can get only existing objects with `existing()` property on your model manager.

```python
queryset = MyModel.objects.existing()
```

#### Get or none

You can get object or `None` if it does not exist with `get_or_none()` method on your model manager.

```python
obj = MyModel.objects.get_or_none(pk=1)
```

### API

#### Views

Inherit your DRF API views from `django_sweet_utils.api.views`:  
  
```
from django_sweet_utils.api.views import UpdateAPIView, DestroyAPIView


class MyUpdateView(UpdateAPIView):
   ...


class MyDestroyView(DestroyAPIView):
   ...
```
  
#### Pagination

There is `PageNumberPagination` class that adds `page_size` query parameter to `PageNumberPagination` class.  
  
```python
REST_FRAMEWORK = {
   ...
   'DEFAULT_PAGINATION_CLASS': 'django_sweet_utils.api.pagination.PageNumberPagination',
   'PAGE_SIZE': 10,
   ...
}
```
  
From now your views supports `POST` request method instead of `PATCH` and `DELETE`
DestroyAPIView does not perform actual database deletion, but only marks file as deleted with `is_deleted=True`
  
### Permissions

#### There is `DjangoModelPermissions` class that adds `view` permission to `DjangoModelPermissions` class on `GET` request method.

### Admin

Hard deletion action for admin panel.

```python
from django_sweet_utils.admin import hard_delete_selected

class MyModelAdmin(admin.ModelAdmin):
    actions = [hard_delete_selected]
```

### Seriliazers

#### Prettier choice field

You can use custom `ChoiceField` instead of `ChoiceField` from `rest_framework` to get prettier choices representation in API.

```python
from django_sweet_utils.api.serializers import ChoiceField

class MySerializer(serializers.ModelSerializer):
    my_field = ChoiceField(choices=MY_CHOICES)
```

#### Prettier multiple choice field

You can use custom `MultipleChoiceField` instead of `MultipleChoiceField` from `rest_framework` to get prettier choices representation in API.

```python
from django_sweet_utils.api.serializers import MultipleChoiceField

class MySerializer(serializers.ModelSerializer):
    my_field = MultipleChoiceField(choices=MY_CHOICES)
```

### Template tags

#### `format_string` template tag

You can use `format_string` template tag to format string with arguments.

```html
{% load django_sweet_utils %}

{{ "Hello, {0}!".format_string("World") }}
```

#### `set_query_string_param` template tag

You can use `set_query_string_param` template tag to set query string parameter.

```html
{% load django_sweet_utils %}

{% set_query_string_param "page" 1 %}
```

More info about this tag you can find [here](django_sweet_utils/templatetags/query_string.py).


### Logging

#### Customised JSON formatter

There is `CustomisedJSONFormatter` class that formats log records as JSON.

```python
from django_sweet_utils.logging import CustomisedJSONFormatter

APP_LABEL = "my_app"
ENVIRONMENT = "production"

formatter = CustomisedJSONFormatter()
```

#### Customised JSON handler

There is `CustomHandler` class that handles log records as JSON.

```python
from django_sweet_utils.logging import CustomHandler

handler = CustomHandler()
```


### Misc

#### Custom JSON encoder

You can use `LazyEncoder` to serialize lazy objects to JSON.

```python
from django_sweet_utils.misc import LazyEncoder

json.dumps({"lazy": lazy_object}, cls=LazyEncoder)
```


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/AllYouZombies/django-sweet-utils",
    "name": "django-sweet-utils",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": "",
    "keywords": "",
    "author": "Astafeev Rustam",
    "author_email": "rustam@astafeev.dev",
    "download_url": "https://files.pythonhosted.org/packages/e4/66/6667c1fa156add7c1bb9d49a4175be663469a2060a301490fc5c116b77ab/django-sweet-utils-1.5.0.tar.gz",
    "platform": null,
    "description": "# Django sweet utils.\n\n[![Downloads](https://static.pepy.tech/personalized-badge/django-sweet-utils?period=total&units=international_system&left_color=black&right_color=orange&left_text=Downloads)](https://pepy.tech/project/django-sweet-utils)\n  \nA little django code sugar.\n  \n> If you find this package useful, please star it on [GitHub](https://github.com/AllYouZombies/django-sweet-utils).\n  \n## Quickstart\n\n1. Add `django_sweet_utils` to your `INSTALLED_APPS` setting like this:\n    ```\n    INSTALLED_APPS = [\n        ...\n        'django_sweet_utils',\n        ...\n    ]\n    ```\n\n2. Inherit your models from `django_sweet_utils.db.models.Model`:\n   ```\n   from django_sweet_utils.db.models import Model\n   \n   \n   class MyModel(Model):\n      ...\n   ```\n   \n   From now your models has the following fields:\n      - `uuid4` as object id;\n      - `created_at` as object creation time;\n      - `updated_at` as object last update time;\n      - `is_deleted` as indicator that object is deleted or not;  \n     \n     \n   Models that inherited from `django_sweet_utils.db.models.Model` can be filtered with simple `existing()` property:\n   ```\n   from django_sweet_utils.db.models import Model\n   \n   \n   class MyModel(Model):\n      ...\n   \n   \n   queryset = MyModel.objects.existing()\n   ```\n   This returns queryset filtered by `is_deleted=False`\n\n   Also, now you don't need to catch `DoesNotExist` error when attempting to get some object while it does not exist.\n   Just use `get_or_none()` instead of `get()` and query returns `None` if there is no object.\n\n\n## Features\n\n### Models\n\n#### Fake deletion\n\nYou can delete your objects without actual database deletion.\nJust use `delete()` method on your model instance and it will be marked as deleted with `is_deleted=True`:\n\nTo perform actual deletion use `hard_delete()` method instead.\n\n#### UUID4 as object id\n\nEvery model instance has `uuid4` field as object id.\n\n#### Created and updated time\n\nEvery model instance has `created_at` and `updated_at` fields as object creation and last update time.\n\n#### Existing objects\n\nYou can get only existing objects with `existing()` property on your model manager.\n\n```python\nqueryset = MyModel.objects.existing()\n```\n\n#### Get or none\n\nYou can get object or `None` if it does not exist with `get_or_none()` method on your model manager.\n\n```python\nobj = MyModel.objects.get_or_none(pk=1)\n```\n\n### API\n\n#### Views\n\nInherit your DRF API views from `django_sweet_utils.api.views`:  \n  \n```\nfrom django_sweet_utils.api.views import UpdateAPIView, DestroyAPIView\n\n\nclass MyUpdateView(UpdateAPIView):\n   ...\n\n\nclass MyDestroyView(DestroyAPIView):\n   ...\n```\n  \n#### Pagination\n\nThere is `PageNumberPagination` class that adds `page_size` query parameter to `PageNumberPagination` class.  \n  \n```python\nREST_FRAMEWORK = {\n   ...\n   'DEFAULT_PAGINATION_CLASS': 'django_sweet_utils.api.pagination.PageNumberPagination',\n   'PAGE_SIZE': 10,\n   ...\n}\n```\n  \nFrom now your views supports `POST` request method instead of `PATCH` and `DELETE`\nDestroyAPIView does not perform actual database deletion, but only marks file as deleted with `is_deleted=True`\n  \n### Permissions\n\n#### There is `DjangoModelPermissions` class that adds `view` permission to `DjangoModelPermissions` class on `GET` request method.\n\n### Admin\n\nHard deletion action for admin panel.\n\n```python\nfrom django_sweet_utils.admin import hard_delete_selected\n\nclass MyModelAdmin(admin.ModelAdmin):\n    actions = [hard_delete_selected]\n```\n\n### Seriliazers\n\n#### Prettier choice field\n\nYou can use custom `ChoiceField` instead of `ChoiceField` from `rest_framework` to get prettier choices representation in API.\n\n```python\nfrom django_sweet_utils.api.serializers import ChoiceField\n\nclass MySerializer(serializers.ModelSerializer):\n    my_field = ChoiceField(choices=MY_CHOICES)\n```\n\n#### Prettier multiple choice field\n\nYou can use custom `MultipleChoiceField` instead of `MultipleChoiceField` from `rest_framework` to get prettier choices representation in API.\n\n```python\nfrom django_sweet_utils.api.serializers import MultipleChoiceField\n\nclass MySerializer(serializers.ModelSerializer):\n    my_field = MultipleChoiceField(choices=MY_CHOICES)\n```\n\n### Template tags\n\n#### `format_string` template tag\n\nYou can use `format_string` template tag to format string with arguments.\n\n```html\n{% load django_sweet_utils %}\n\n{{ \"Hello, {0}!\".format_string(\"World\") }}\n```\n\n#### `set_query_string_param` template tag\n\nYou can use `set_query_string_param` template tag to set query string parameter.\n\n```html\n{% load django_sweet_utils %}\n\n{% set_query_string_param \"page\" 1 %}\n```\n\nMore info about this tag you can find [here](django_sweet_utils/templatetags/query_string.py).\n\n\n### Logging\n\n#### Customised JSON formatter\n\nThere is `CustomisedJSONFormatter` class that formats log records as JSON.\n\n```python\nfrom django_sweet_utils.logging import CustomisedJSONFormatter\n\nAPP_LABEL = \"my_app\"\nENVIRONMENT = \"production\"\n\nformatter = CustomisedJSONFormatter()\n```\n\n#### Customised JSON handler\n\nThere is `CustomHandler` class that handles log records as JSON.\n\n```python\nfrom django_sweet_utils.logging import CustomHandler\n\nhandler = CustomHandler()\n```\n\n\n### Misc\n\n#### Custom JSON encoder\n\nYou can use `LazyEncoder` to serialize lazy objects to JSON.\n\n```python\nfrom django_sweet_utils.misc import LazyEncoder\n\njson.dumps({\"lazy\": lazy_object}, cls=LazyEncoder)\n```\n\n",
    "bugtrack_url": null,
    "license": "MIT License",
    "summary": "A little django code sugar.",
    "version": "1.5.0",
    "project_urls": {
        "Homepage": "https://github.com/AllYouZombies/django-sweet-utils"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "9de82562a4df30a4444d45572f8bc53cb7bcb1e15c534a8420941dadc95df56f",
                "md5": "f6e262cab748a95fea9d9290ad7286cb",
                "sha256": "42beace9fef6bc47f91f5615cba0bb33b953e11c2cd489a7118e1f6157d84aeb"
            },
            "downloads": -1,
            "filename": "django_sweet_utils-1.5.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "f6e262cab748a95fea9d9290ad7286cb",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 12674,
            "upload_time": "2023-06-15T06:48:13",
            "upload_time_iso_8601": "2023-06-15T06:48:13.429237Z",
            "url": "https://files.pythonhosted.org/packages/9d/e8/2562a4df30a4444d45572f8bc53cb7bcb1e15c534a8420941dadc95df56f/django_sweet_utils-1.5.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e4666667c1fa156add7c1bb9d49a4175be663469a2060a301490fc5c116b77ab",
                "md5": "42fd21c1d7daa426384ccb4cac9a906f",
                "sha256": "fc8a67ed886e2aaed06c8f2edfbab242f04cf6cd6af2421b73f11ea8a7eabfb2"
            },
            "downloads": -1,
            "filename": "django-sweet-utils-1.5.0.tar.gz",
            "has_sig": false,
            "md5_digest": "42fd21c1d7daa426384ccb4cac9a906f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 11569,
            "upload_time": "2023-06-15T06:48:15",
            "upload_time_iso_8601": "2023-06-15T06:48:15.281147Z",
            "url": "https://files.pythonhosted.org/packages/e4/66/6667c1fa156add7c1bb9d49a4175be663469a2060a301490fc5c116b77ab/django-sweet-utils-1.5.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-06-15 06:48:15",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "AllYouZombies",
    "github_project": "django-sweet-utils",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [],
    "lcname": "django-sweet-utils"
}
        
Elapsed time: 0.07874s