this module collects helper functions and classes that span multiple levels of mvc in other words these functionsclasses introduce controlled coupling for convenience s sake return an httpresponse whose content is filled with the result of calling django template loader rendertostring with the passed arguments return an httpresponseredirect to the appropriate url for the arguments passed the arguments could be a model the model s getabsoluteurl function will be called a view name possibly with arguments urls reverse will be used to reverseresolve the name a url which will be used asis for the redirect location issues a temporary redirect by default pass permanenttrue to issue a permanent redirect return a queryset or a manager duck typing in action any class with a get method for getobjector404 or a filter method for getlistor404 might do the job if it is a model class or anything else with defaultmanager use get to return an object or raise an http404 exception if the object does not exist klass may be a model manager or queryset object all other passed arguments and keyword arguments are used in the get query like with queryset get multipleobjectsreturned is raised if more than one object is found see getobjector404 queryset getquerysetklass if not hasattrqueryset aget klassname klass name if isinstanceklass type else klass class name raise valueerror first argument to agetobjector404 must be a model manager or fqueryset not klassname try return await queryset agetargs kwargs except queryset model doesnotexist raise http404fno queryset model meta objectname matches the given query def getlistor404klass args kwargs queryset getquerysetklass if not hasattrqueryset filter klassname klass name if isinstanceklass type else klass class name raise valueerror first argument to getlistor404 must be a model manager or queryset not s klassname objlist listqueryset filterargs kwargs if not objlist raise http404 no s matches the given query queryset model meta objectname return objlist async def agetlistor404klass args kwargs return a url appropriate for the arguments passed the arguments could be a model the model s getabsoluteurl function will be called a view name possibly with arguments urls reverse will be used to reverseresolve the name a url which will be returned asis if it s a model use getabsoluteurl expand the lazy instance as it can cause issues when it is passed further to some python functions like urlparse handle relative urls next try a reverse url resolution if this is a callable reraise if this doesn t feel like a url reraise finally fall back and assume it s a url return an httpresponse whose content is filled with the result of calling django template loader render_to_string with the passed arguments return an httpresponseredirect to the appropriate url for the arguments passed the arguments could be a model the model s get_absolute_url function will be called a view name possibly with arguments urls reverse will be used to reverse resolve the name a url which will be used as is for the redirect location issues a temporary redirect by default pass permanent true to issue a permanent redirect return a queryset or a manager duck typing in action any class with a get method for get_object_or_404 or a filter method for get_list_or_404 might do the job if it is a model class or anything else with _default_manager use get to return an object or raise an http404 exception if the object does not exist klass may be a model manager or queryset object all other passed arguments and keyword arguments are used in the get query like with queryset get multipleobjectsreturned is raised if more than one object is found see get_object_or_404 use filter to return a list of objects or raise an http404 exception if the list is empty klass may be a model manager or queryset object all other passed arguments and keyword arguments are used in the filter query see get_list_or_404 return a url appropriate for the arguments passed the arguments could be a model the model s get_absolute_url function will be called a view name possibly with arguments urls reverse will be used to reverse resolve the name a url which will be returned as is if it s a model use get_absolute_url expand the lazy instance as it can cause issues when it is passed further to some python functions like urlparse handle relative urls next try a reverse url resolution if this is a callable re raise if this doesn t feel like a url re raise finally fall back and assume it s a url
from django.http import (
    Http404,
    HttpResponse,
    HttpResponsePermanentRedirect,
    HttpResponseRedirect,
)
from django.template import loader
from django.urls import NoReverseMatch, reverse
from django.utils.functional import Promise


def render(
    request, template_name, context=None, content_type=None, status=None, using=None
):
    
    content = loader.render_to_string(template_name, context, request, using=using)
    return HttpResponse(content, content_type, status)


def redirect(to, *args, permanent=False, **kwargs):
    
    redirect_class = (
        HttpResponsePermanentRedirect if permanent else HttpResponseRedirect
    )
    return redirect_class(resolve_url(to, *args, **kwargs))


def _get_queryset(klass):
    
    
    if hasattr(klass, "_default_manager"):
        return klass._default_manager.all()
    return klass


def get_object_or_404(klass, *args, **kwargs):
    
    queryset = _get_queryset(klass)
    if not hasattr(queryset, "get"):
        klass__name = (
            klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
        )
        raise ValueError(
            "First argument to get_object_or_404() must be a Model, Manager, "
            "or QuerySet, not '%s'." % klass__name
        )
    try:
        return queryset.get(*args, **kwargs)
    except queryset.model.DoesNotExist:
        raise Http404(
            "No %s matches the given query." % queryset.model._meta.object_name
        )


async def aget_object_or_404(klass, *args, **kwargs):
    
    queryset = _get_queryset(klass)
    if not hasattr(queryset, "aget"):
        klass__name = (
            klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
        )
        raise ValueError(
            "First argument to aget_object_or_404() must be a Model, Manager, or "
            f"QuerySet, not '{klass__name}'."
        )
    try:
        return await queryset.aget(*args, **kwargs)
    except queryset.model.DoesNotExist:
        raise Http404(f"No {queryset.model._meta.object_name} matches the given query.")


def get_list_or_404(klass, *args, **kwargs):
    
    queryset = _get_queryset(klass)
    if not hasattr(queryset, "filter"):
        klass__name = (
            klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
        )
        raise ValueError(
            "First argument to get_list_or_404() must be a Model, Manager, or "
            "QuerySet, not '%s'." % klass__name
        )
    obj_list = list(queryset.filter(*args, **kwargs))
    if not obj_list:
        raise Http404(
            "No %s matches the given query." % queryset.model._meta.object_name
        )
    return obj_list


async def aget_list_or_404(klass, *args, **kwargs):
    
    queryset = _get_queryset(klass)
    if not hasattr(queryset, "filter"):
        klass__name = (
            klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
        )
        raise ValueError(
            "First argument to aget_list_or_404() must be a Model, Manager, or "
            f"QuerySet, not '{klass__name}'."
        )
    obj_list = [obj async for obj in queryset.filter(*args, **kwargs)]
    if not obj_list:
        raise Http404(f"No {queryset.model._meta.object_name} matches the given query.")
    return obj_list


def resolve_url(to, *args, **kwargs):
    
    
    if hasattr(to, "get_absolute_url"):
        return to.get_absolute_url()

    if isinstance(to, Promise):
        
        
        to = str(to)

    
    if isinstance(to, str) and to.startswith(("./", "../")):
        return to

    
    try:
        return reverse(to, args=args, kwargs=kwargs)
    except NoReverseMatch:
        
        if callable(to):
            raise
        
        if "/" not in to and "." not in to:
            raise

    
    return to