Package: fatbox-django-utils
This is a collection of general utilities for Django projects built by FatBox.InstallationInstall using pip:pip install fatbox-django-utilsIf you’re going to use the Template Tags then you also need to addfatbox_utilsto yourINSTALLED_APPSsetting.These utilities require Django 1.3+. They may work with earlier versions but
haven’t been tested.Rendering templatesrender_to decoratorTherender_todecorator allows you to very easily render templates from
your view functions. Simply decorate your view function and specify the name
of the template to render to, then return a dict from your view function that
contains variables that will be in the context when rendering the template.fromfatbox_utils.decoratorsimportrender_to@render_to('myapp/template.html')defmyview(request):return{'var1':var1,'var2':var2}You can change the template on the fly by returning a list or tuple where the
first element is the name of the template and the second element is the dict to
use for the context.@render_to('myapp/template.html')defmyview(request):context={'var1':var1,'var2':var2}# if something is true then use our other templateifsomething_is_true:return('other_template.html',context)# otherwise use the default templatereturncontextLastly if you don’t return a dict or a list/tuple thenrender_towill just
return what you give it. This ensures that if you return things likeHttpResponseRedirectobjects they will work as expected, but also means
that you are free to craft your own response should it be required. Anything
that’s valid to return from a standard Django view will work.Humanizehumanize_time functionThehumanize_timefunction summarizes time based on the units you provide
to it. For example here is what is run in the doc tests:>>>fromfatbox_utils.humanizeimporthumanize_time>>>humanize_time(173,"hours")u'1 week, 5 hours'>>>humanize_time(17313,"seconds")u'4 hours, 48 minutes, 33 seconds'>>>humanize_time(5400,"seconds")u'1 hour, 30 minutes'>>>humanize_time(90,"weeks")u'1 year, 10 months, 2 weeks'>>>humanize_time(42,"months")u'3 years, 6 months'>>>humanize_time(500,"days")u'1 year, 5 months, 3 weeks, 3 days'See:http://stackoverflow.com/a/6574789Cachedelete_template_fragment_cache functionThis is a function that deletes a named template fragment cache.See:http://djangosnippets.org/snippets/2723/In your template:{%loadcache%}{%cache3600my_cache_blockrequest.user.username%}...{%endcache%}And in your view:fromfatbox_utils.cacheimportdelete_template_fragment_cachedefmy_view(request):...delete_template_fragment_cache("my_cache_block",request.user.username)...i18n / TranslationThis package includes a number of different utilities for managing and working
with i18n / translation in your project.current_lang context processorThis is a context processor that addscurrent_langto your template context
as a 2 letter language code (ie.en,fr,pt, etc).Just addfatbox_utils.context_processors.current_langto theTEMPLATE_CONTEXT_PROCESSORSsetting.ManualLanguageMiddlewareThis is a middleware class that allows you to force the language used by the
Django translation layer based on a querystring parameter.To use it simply addfatbox_utils.middleware.ManualLanguageMiddlewareto
theMIDDLEWARE_CLASSESsetting. Then you can pass a two character language
code to a get parameter namedlangto activate a specific language.translatable_property for ModelsOften times when working on a project that deals with multiple languages you
want to have certain properties of a model translatable. Thetranslatable_propertyclass provides a convenient interface to define your
properties that should be available in multiple languages.Consider the following examplemodels.pyfile:fromdjango.dbimportmodelsfromfatbox_utils.i18nimporttranslatable_property,TranslatableModelclassEvent(models.Model):start=models.DateTimeField()end=models.DateTimeField()title=translatable_property('title','translations')details=translatable_property('details','translations')classEventTranslation(TranslatableModel):event=models.ForeignKey(Event,related_name='translations')title=models.CharField(max_length=32)details=models.TextField()What this does is add two modelsEventandEventTranslationwhere theEventTranslationmodel has a foreign key toEventand sets up a related
manager namedtranslations.TheEventTranslationmodel extends fromTranslatableModelso that it will
have the requiredlanguagefield setup. Thelanguagefield is a CharField
withmax_length=2, choices=settings.LANGUAGESset for options. If you require
different handling for your language selection you can simply extend from Django’s
basemodels.Modeland define your ownlanguagefield.On theEventmodel we define two properties using thetranslatable_propertyclass. When defining these properties the first argument is the field on the
related model and the second argument is the name of the manager that we can use
to lookup the related model that corresponds to the current language.When you access one of thetranslatable_propertyproperties on your model
it will try to fetch the related object from thetranslationsmanager where
the related object has a field namedlanguagethat matches the current
language, as defined by theget_languagefunction from thedjango.utils.translationpackage. If it can’t find a related object with a
matchinglanguagefield it will then try to get one with the default
language, as defined bysettings.DEFAULT_LANGUAGE.Performance OptimizationIf you don’t do any optimization of your querysets once you reach even a modest
number ofEventobjects iterating over their querysets can become a HUGE
burden on your database due to the number of SELECT lookups it needs to do when
fetching all of the relatedEventDescriptionobjects.To combat this you can use Django’sprefetch_relatedqueryset function to
fetch all of the related translations in one fell swoop, reducing the number of
queries to 2.Event.objects.filter(...).prefetch_related('translations')Admin IntegrationOnce you have your models setup withtranslatable_propertythen you can
simply use normalDjango Inlineswithout having to worry about complex admin
site configuration.Template TagsSmart SpacelessThe Django{% spaceless %}tag is a great way to optimize your templates
so that you send the smallest amount of data possible to clients, however when
you’re in development turning spaceless on makes it hard to read your HTML and
debug problems.The{% smart_spaceless %}tag works exactly the same as the normal tag,
except that it only applies spaceless when yourDEBUGsetting isFalse.{%loadsmart_spaceless%}{%smart_spaceless%}<!doctype html><html>...</html>{%end_smart_spaceless%}URL ToolsThe URL Tools template tags provide some convenience functions when working
with URLs in your templates. They all require that therequestbe available
in the current context so make sure that you havedjango.core.context_processors.requestenabled in yourTEMPLATE_CONTEXT_PROCESSORSsetting.build_absolute_uriThis exposes thebuild_absolute_urifunction of the request object to your
templates.{%loadurltools%}<ahref="{%build_absolute_urimyobject.get_absolute_url%}">Link</a>modify_querystringThis allows you to modify individual querystring parameters, without needing
to reconstruct the entire URL.For example, say you’re on a page that shows a listing of objects and you have
flags for determining if the user will view the results as a grid or as a list.
On this same view you may accept a querystring parameter to further limit the
query so having to manually reconstruct the URL just to change the format
becomes a much more complex task. Withmodify_querystringwe can change
just theformatquerystring parameter (even adding it if it doesn’t exist)
without having to reconstruct anything.{%loadurltools%}<div><span>Sort:</span><ahref="{%modify_querystringsort="date"%}"{%ifsort_by=="date"%}class="active"{%endif%}>By Date</a>|<ahref="{%modify_querystringsort="title"%}"{%ifsort_by=="title"%}class="active"{%endif%}>Alphabetically</a></div><div><span>View as:</span><ahref="{%modify_querystringformat="list"%}"{%ifpage_format=="list"%}class="active"{%endif%}>List</a>|<ahref="{%modify_querystringformat="grid"%}"{%ifpage_format=="grid"%}class="active"{%endif%}>Grid</a></div>