Last active
July 6, 2023 11:07
-
-
Save Tobi-De/05e76ac3503a2776cf95115f9b49811f to your computer and use it in GitHub Desktop.
Some django utils I usually have in my projects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# render pdf using weasyprint | |
# depends on: weasyprint | |
import weasyprint | |
from django.template.loader import render_to_string | |
def render_to_pdf(template_src, context_dict=None): | |
html = render_to_string(template_src, context_dict) | |
try: | |
pdf = weasyprint.HTML(string=html).write_pdf() | |
except Exception as e: | |
logger.error(f"Pdf rendering: {e}") | |
return None | |
return pdf | |
# qosic mobile money payment client | |
# depends on: qosic-sdk | |
QOSIC = { | |
"moov_id": env("MOOV_CLIENT_ID"), | |
"mtn_id": env("MTN_CLIENT_ID"), | |
"login": env("QOSIC_SERVER_LOGIN"), | |
"password": env("QOSIC_SERVER_PASS"), | |
} | |
from django.conf import settings | |
from qosic import Client, MtnConfig, MTN, MOOV | |
def get_qosic_client() -> Client: | |
providers = [ | |
MTN( | |
client_id=settings.QOSIC.get("mtn_id"), | |
config=MtnConfig(step=30, timeout=60 * 2), | |
), | |
MOOV(client_id=settings.QOSIC.get("moov_id")), | |
] | |
return Client( | |
providers=providers, | |
login=settings.QOSIC.get("login").strip(), | |
password=settings.QOSIC.get("password").strip(), | |
) | |
# add a filtered table in a function view context data | |
# depends on: django-filter, django-tables2 | |
from typing import Any, Type | |
import django_filters as filters | |
import django_tables2 as table | |
def paginated_table_context_data( | |
queryset: QuerySet, | |
*, | |
request: HttpRequest, | |
table_class: Type[tables.Table], | |
filter_class: Optional[Type[filters.FilterSet]] = None, | |
paginage_by: int = 10, | |
) -> dict[str, Any]: | |
context = {} | |
if filter_class: | |
context["filter"] = filter_class(request.GET) | |
filterset = filter_class(request.GET, queryset=queryset) | |
if filterset.is_bound or filterset.is_valid(): | |
qs = filterset.qs | |
else: | |
qs = filterset.queryset.none() | |
else: | |
qs = queryset | |
table = table_class(data=qs, request=request) | |
page_number = int(request.GET.get("page", 1)) | |
table = table.paginate(page=page_number, per_page=paginage_by) | |
context["table"] = table | |
return context | |
# htmx decorator for function based views | |
# depends on: django-htmx | |
from functools import wraps | |
def htmx_view(full_template: str, partial_template: str): | |
def inner(view): | |
@wraps(view) | |
def func(request, *args, **kwargs): | |
context: dict = view(request, *args, **kwargs) | |
template = partial_template if request.htmx else full_template | |
return TemplateResponse(request, template, context) | |
return func | |
return inner | |
# file upload_to | |
def user_upload_to(instance: Any, filename: str, category: str): | |
return f"users/{instance.id}/{category}/{filename}" | |
# lazily evaluate context processor data, this trick can be used with any data anywhere | |
from functools import lru_cache | |
def my_context_processor(request): | |
@lru_cache() | |
def complicated_query(): | |
result = do_stuff() | |
return result | |
return {'my_info': complicated_query} | |
# view decorator | |
def require(methods=("GET", "POST"), login=True): | |
def decorator(func): | |
wrapped = func | |
if methods is not None: | |
wrapped = require_http_methods(methods)(func) | |
if login: | |
wrapped = login_required(func) | |
return wrapped | |
return decorator | |
# return html for django-tables column | |
def render_actions(self, value: str, **kwargs): | |
html = ( | |
TemplateResponse( | |
request=self.request, | |
template="customers/partials/delete_button.html", | |
context={"delete_url": value}, | |
) | |
.render() | |
.rendered_content | |
) | |
return mark_safe(html) | |
# load data into tablib from django.core.files.File | |
def import_from_file(cls, file: File) -> list | None: | |
filename, extension = os.path.splitext(file.name) | |
file_format = extension[1:] | |
if file_format in ["xls", "xlsx"]: | |
databook = tablib.Databook().load(file.read(), format=file_format) | |
dataset = databook.sheets()[0] | |
else: | |
dataset = tablib.Dataset().load( | |
file.read().decode("utf-8"), format=file_format | |
) | |
result = cls().import_data( | |
dataset=dataset, | |
use_transactions=True, | |
rollback_on_validation_errors=True, | |
collect_failed_rows=True, | |
) | |
if result.has_errors(): | |
return result.row_errors() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment