django-awesome-tools GitHub Details, Stars and Alternatives | OpenRepoFinder
cayo-rodrigues / repository
django-awesome-tools
Um projeto feito para facilitar a vida de desenvolvedores, trazendo algumas funcionalidades comuns já prontas, de maneira simples de usar. Trata-se de um pacote Python, que possui funções e classes úteis para serem usadas em projetos Django, especialmente com Django Rest Framework.
A transparent discovery signal based on current public GitHub metadata.
Recent activity35% weight
10
Community adoption25% weight
9
Maintenance state20% weight
100
License clarity10% weight
100
Project information10% weight
92
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
README preview
This package provides useful and powerful functions and classes to be used in Django projects, specially when working with Django Rest Framework. Below are some further explation about how to use this package and what each module inside it does.
Um projeto que permite o gerenciamento e exposição de tecnologias conhecidas e projetos feitos. Esta aplicação foi feita utilizando Django e Django Rest Framework, além disso é totalmente testada. O objetivo é ser uma API para uma outra aplicação Front End de mesmo nome.
This module provides three useful functions. Two of them are a more powerful and versatille version of get_object_or_404 and get_list_or_404, and the other is a handy shortcut.
get_object_or_error
Almost the same as django.shortcuts.get_object_or_404, but can raise any
custom error class you want, allowing you to return more precise error messages.
Another advantage of using this helper function, is that it prevents your application
from crashing. For instance, in case you want to get an object by it's primary key, and
it is of type uuid, but another data type is provided in the url, it will not crash,
unlike the standard get_object_or_404. It expects the following arguments:
klass -> The model that will be used for the query
exception -> An error class inheriting from rest_framework.exceptions.APIException.
If no exception is provided, then the standard django.http.Http404 class is used.
**kwargs -> Keyword arguments representing all fields that should be used for the
search, as many as you please.
For instance, in case you want to get a Room of a Cinema:
# exceptions.py
from rest_framework.exceptions import APIException, status
class CinemaNotFoundError(APIException):
status_code = status.HTTP_404_NOT_FOUND
default_detail = "Cinema not found"
class RoomNotFoundError(APIException):
status_code = status.HTTP_404_NOT_FOUND
default_detail = "Room not found in this cinema"
Note that in case a room id is valid, but the cinema id is not, an appropriated message will be
returned. In case you would use get_object_or_404, you would get just a "Not found.". Having
more than one lookup field, get_object_or_error makes much clearer what is the problem.
I highly encorage you to have a quick look at the source code, it's quite a simple concept.
get_list_or_error
Almost the same as django.shortcuts.get_list_or_404, but can raise any
custom error class you want, allowing you to return more precise error messages.
Another advantage of using this helper function, is that it prevents your application
from crashing. For instance, in case you want to get a list, filtering it by some foreign
key field, which is of type uuid, but another data type is provided in the url, it will
not crash, unlike the standard get_list_or_404. Also, this function gives you the possiblity
of not raising an exception when no values are found, so you could just return an empty list.
It expects the following arguments:
klass -> The model that will be used for the query
exception -> An error class inheriting from rest_framework.exceptions.APIException.
If no exception is provided, then the standard django.http.Http404 class is used.
accept_empty -> A boolean argument, which defaults to False. When provided, determines
if an empty result is acceptable or if it should raise exception.
**kwargs -> Keyword arguments representing all fields that should be used for the
search, as many as you please.
For instance, in case you want to list all MovieSessions of a Room in a Cinema:
# exceptions.py
from rest_framework.exceptions import APIException, status
class NoMovieSessionsError(APIException):
status_code = status.HTTP_404_NOT_FOUND
default_detail = "This room has no scheduled movie sessions"
I highly encorage you to have a quick look at the source code, it's quite a simple concept.
set_and_destroy
This function basically sets a new list of values in a foreign key field and erases any
previous values that were related to klass. For it to work, you must set null=True
in your model, otherwise, the values will not be subsitituted, they will only be added.
It accepts the following parameters:
klass -> The model on the side 1 of a 1:N relationship, the owner of the relation,
in which the new values will be set
attr -> A string version of the attribute corresponding to the related_name value
in the foreign key field
value -> A list (or any other iterable), containing new created instances of related_klass
related_klass -> The model on the side N of a 1:N relationship, the one having the foreign
key field
**kwargs -> Keyword arguments used in a filter to determine which objects should be destroyed.
It could be really anything, but usually you will want it to be something like klass=None, so
that all objects that are no part of the relationship anymore can be descarded.
For instance, a Movie may have many Videos related to it, like teasers and trailers. In case
you want to update a Movie, reseting its Videos:
# models.py
class Movie(models.Model):
...
class Video(models.Model):
id = models.UUIDField(primary_key=True, editable=False, default=uuid4)
title = models.CharField(max_length=127)
url = models.URLField()
movie = models.ForeignKey(Movie, on_delete=models.CASCADE, related_name="videos", null=True)
# serializers.py
from awesome_tools.helpers import set_and_destroy
class MovieSerializer(serializers.ModelSerializer):
...
def update(self, instance: Movie, validated_data: dict):
...
videos_data = validated_data.pop("videos", None)
if videos_data:
videos = [
Video.get_or_create(**video, movie=instance)[0]
for video in videos_data
]
set_and_destroy(
klass=instance,
attr="videos",
value=videos,
related_klass=Video,
movie=None,
)
In the example above, we are first getting or creating video instances, in order to reuse the ones
passed in the body of the request that may already be in our db. Each video can only be related to
one movie, since it doesn't make sense that two movies have the same trailer or teaser. So when
assigning this new list of videos to a movie, the set_and_destroy function safely deletes all
videos having their movie foreign key equal to None.
I highly encorage you to have a quick look at the source code, it's quite a simple concept.
bulk_get_or_create
Despite the name of this function, it does not translate into a single database hit,
unfortunatelly. But it is still better than a loop executing Model.objects.get_or_create
in every iteration.
That's because this function combines filters and the bulk_create method.
Django querysets are lazy, but in this function they are evaluated on every iteration.
However, in the end only oneINSERT query is performed.
Important!
Django's Model.objects.bulk_create method returns a list of newly created instances without ids
when working with SQLite. Please, make sure to use PostgreSQL to avoid problems.
It expects the following parameters:
klass -> The model whose values will be retrieved or created
values -> A list of dictionaries having key value pairs demanded by klass
only_create -> A boolean value. Defaults to False. In case you don't care about getting
existing values, and just wants to create them, then you can set this arguments to True. It
will result in just one database hit.
kwargs -> Key value pairs with extra fields you want to use for filtering/creating instances
of klass. It can be useful for foreign key fields