Django: Using Different Templates for Production - django

In my base.html template which is imported in every Django template, I have a block with the Google Analytics script:
<!-- GOOGLE ANALYTICS -->
<script type="text/javascript">
bla bla...
</script>
I would like to have this script only included when in production, but not during development. Is there a solution for this comparable to the solution in setting.py?
import socket
if socket.gethostname() == 'my-laptop':
DEBUG = TEMPLATE_DEBUG = True
else:
DEBUG = TEMPLATE_DEBUG = False
Anybody who knows of a template tag, or should I do my own one?

You could add your DEBUG variable to a context processor and just put an IF around that block.
http://docs.djangoproject.com/en/dev/ref/templates/api/#subclassing-context-requestcontext
from django.conf import settings
def debug_context(request):
return {'DEBUG': settings.DEBUG}
Then in your template:
{% if DEBUG %}
STUFF
{% endif %}
Alternatively you could make the context processor return anything you want to key off of, anything in your settings file or otherwise.

In settings.py,Check debug is True, also add:
INTERNAL_IPS = (
'127.0.0.1',
'localhost',
)
Then you can use things in your template like this:
{% if debug %}
<span>This is debug</span>
{% else %}
<span>This is production</span>
{% endif %}
If want to change to production, set debug to False.
Ref:
http://www.djangobook.com/en/2.0/chapter09.html

Haven't seen such a template tag yet.
I'm more inclined to use different setting.py files for production and dev, and include analytics code as described in this answer.
This solution allows for a simpler template, and gives you the option to use different analytics code in different deployments of the same app.

The template is probably not the best place to handle this.
usually, you'd write a context preprocessor that will process the request and add a flag to your context (such as PRODUCTION = True). Then you can use a simple if statement in the template, or better yet, write a simple custom tag that will hide that implementation detail from the template.
See also this answer.

I do the following on lots of sites and it seems to work really well.
Then in my static media file directory I have a copy of base.css and base_dev.css. I do all my development in the base_dev.css file then merge it into base.css before I launch.

Related

Recursive app dependencies django

Django's INSTALLED_APPS is a list in the settings file, which ultimately the devops girl/guy of the wsgi-application is responsible for.
However, when creating an app, I often use templates and templatetags of other apps, for example django-bootstrap4. Consider a simple bootstrap4-with-butter app, that only proivides this template:
bs4wb/templates/bs4wb/base.html
{% extends "bootstrap4/bootstrap4.html" %}
{% block bootstrap4_extra_head %}
<script> confirm('with butter?!'); </script>
{% endblock bootstrap4_extra_head %}
It is not enough for the devops to install and add to INSTALLED_APPS
bs4wb, they also need to do the same for django-bootstrap4, and moreover, he/she also needs to keep track of the version I used whenever I upgrade from django-bootstrap4 to django-bootstrap5` or something. That is, I need to document an extra step which can change.
How can I specify recursive INSTALLED_APPS? Is there something like an app-union? For example (obviously ugly syntax, sorry):
export('bs4wb', app_by_union(['bootstrap4', 'bs4wb']) )
which would insert bootstrap4 and bs4wb next to each other whenever bs4wb is added to INSTALLED_APPS?
Or should I just raise an exception if bootstrap4 was not added to installed apps, stating that it should be added.
As an app developer you usually use django's system check framework to ensure the environment fits your requirements.
In your case you'll check whether another app is included in INSTALLED_APPS and add an error, if not.
It might look like that (untested):
from django.conf import settings
from django.core.checks import Error, register
#register()
def bootstrap4_check(app_configs, **kwargs):
errors = []
if not 'django-bootstrap4' in settings.INSTALLED_APPS:
errors.append(
Error('django-bootstrap4 needs to be in INSTALLED_APPS')
)
return errors
If your requirements change with new versions: adjust the checks.

Using Nunjucks in flask app - Trying to include HTML

I'm using Nunjucks apart from Jinja2 in my Flask application so I can pass in some variables through JS that I want to render in an HTML template.
-- Here's what I do --
JS controller:
this.element = DomHelper.htmlToDom( slideTemplate.render({ slide : this.model }));
{% include "presentation/slide/layouts/layout-1.html/" %}
What I have working:
Nunjucks compiles & render works properly without the {% include..}
slide variable is being passed and used fine
Any thoughts or suggestions would be nice. Thanks!
So I found that I had overlooked a simple thing. My nunjucks was configured to work only for the client side but the templates are served through flask. The relative path will only work for the client side data.
Solution: I placed the template layouts inside the static/ directory instead of in server-side templates/
Based on your question, you might have a typo. You have:
{% include "presentation/slide/layouts/layout-1.html" %}
but you say:
The desired html template I want to includes is in
templates/presentations/slide/layouts/ - Here's my folder structure
Is the path templates/presentations OR templates/presentation ?

Calling python "DIR" function from django template, or php print_r equivalent?

Does anyone know of an existing library for inspecting elements in the template?
Currently I usually end up doing this in the view:
show_me = dir(the_deets_on_this_object)
raise ValueError()
Then I can inspect the value of show_me in the debugger stack trace.
However, this is really ugly. I'd love to be able to do this inspection in the template, like is done in php with the print_r
{% load development_show_me %}
{{the_deets_on_this_object|show_them_to_me}}
I know that this doesn't exist in the django standard template library, but I'm hoping someone has already written this template filter so I can just happily use it.
Bonus behaviors:
Checks for settings.DEBUG and raises an error that isn't trapped if it is false
wraps the output in < pre >
I'll write it if I have to, but hopefully someone else has already done this.
It ended up being faster to write the feature than to write the question asking if anyone knew if it existed.
#myproject/tempates/templatetags/helper_tags.py
from django.template import Library
from django.conf import settings
register = Library()
#register.simple_tag
def template_dir(this_object, its_name=""):
if settings.DEBUG:
output = dir(this_object)
return "<pre>" + str(its_name) + " " + str(output) + "</pre>"
return ""
Usage:
{% load helper_tags %}
{% template_dir field.field "field.field" %}
{% template_dir my_object "I'm looking at my_object" %}
In django there is much better than print_r:
if the template crashes, you have access to all variable in the debig template. you can force this by settings {% url fjkdslmjfdklmfjlsmqk %}
It's like a super print_r on all variables.
you can install django(extensions and werkzeug, this way you can replace runserver with runserver_plus and get the same page as the one we talked about, but with interactive Python shell embeded at every line of the stack trace
you can install django_template_repl, which will let you start the debugger at anyplace in the template, in the form of a python shell or a template shell.
you can install the django-debug-toolbar to get print_r style display and much more in a JS side bar invisible to anybody but you.
I'm from a Drupal/PHP background and Debugger Tags helped me find something familiar to that environment.
"Allows you to use debugger breakpoints on Django templates."
after following the simple install, put this at the top of your template:
{% load debugger_tags %}
Then use this syntax for either the ipdb, pdb or wdb filters:
{% for object in object_list %}
{{ object|pdb }}
{% endfor %}
Refresh the browser window your template is using. Then go into your terminal/shell where you are running the python/django server and explore the object:
-> return obj
(Pdb) dir(obj)
After looking at the valid attributes returning from dir() I can find and explore what I need to put into the template:
(Pdb) obj.post_category
<PostCategory: Meme>
(Pdb) obj.post_category.name
'Meme'
When exploring an object:
(Pdb) pp(obj.__dict__)
Hope this helps a noob like me :-J
Not sure is it what you looking for, but django has default template filter pprint. Looks like this is print_r replacer.

Flex 4 + Django: Testing and Release Options

I am creating a django-based site that will serve flash apps that occasionally access data via pyamf. I need to be able to easily test the flash in the context of the django framework, i.e. with all the login cookies and everything available, so that when I make a pyamf call, it has all the user context there. And I need to be able to test and release both the swf's and the wrapper html's in a sane way. However:
The html templates in flex are already templates, so if I put template code in there for django, it gets scraped out before the flashapp.html is created.
The html's and swf's automatically get released to the same directory, but I want them to go to different directories because the swf's shouldn't be served by django and the html's should be in an area in control of django.
This leads me to believe, at first glance, that I need:
A way of having the html and swf files be released to different locations. (I don't know how to do this.)
A way of releasing the html's as stubs (no html/body tag) so that I can include them from another location in django. (I guess just strip what I don't want from the index.template.html?)
Then I can point flex to go to the django site that in turn includes the generated flashapp.html that in turn references the swf, and it should all work. (By feeding that alternate html to the run/debug settings, I assume.)
So my question comes down to:
Is the above the best way of doing this, or is this even the right direction?
If so, how do I release the html and swf to different directories? (For debug and release mode, if there are two different methods.)
If not, what is proper?
And if there are any other general bits of advice for me on this topic, please feel free to share. :-)
Finally figured this out myself. A combination of this and django get-parameters works. The general take-away:
You can put {% tags %} and {{ variables }} in index.template.html without worry, as there is no way to customize the currently-existing macros there like ${title}
If you make a foo.template.html and foo-debug.template.html in the html-template directory of your project, then the former will override index.template.html for release builds, and the latter for debug builds (note that the result will be foo-debug.html instead of foo.html though.)
You can pass the name of the SWF in a parameter to django, and have it fill in the directory for you
foo-debug.template.html
<object ...
<param name="movie" value="{{ bin_debug_url }}/${swf}.swf" ...
djangoflash.html
{% block content %}
{% include flash_template %}
{% endblock %}
views.py
def djangoflashview( request, **kwargs ):
if not kwargs.has_key('extra_context'):
kwargs['extra_context'] = {}
if request.GET.has_key('name'):
debug = "-debug" if request.GET.has_key('debug') else ""
bin_debug_dir = '/dir-to-bin-debug/'
bin_debug_url = 'url-to-bin-debug'
name = bin_debug_dir + request.GET['name'] + debug + '.html'
kwargs['extra_context']['flash_template'] = name
kwargs['extra_context']['bin_debug_url' ] = bin_debug_url
return direct_to_template( request, **kwargs )
urls.py
url( r'^djangoflash/', 'views.djangoflashview',
{ 'template': 'djangoflash.html' }
foo.mxml's run-debug target:
/url-to-django/djangoflash/?name=foo
When you debug foo.mxml, flex:
Adds &debug=true to the url
Brings up a browser to /url-to-djangoflash/djangoflash/?name=foo&debug=true
Which picks djangoflash/ in urls.py
Which passes the request to djangoflashview and {'name':'foo','debug':'true'} to request.GET in views.py
Which figures out the name and location of the foo-debug.html location, passing it to the flash_template context variable
And the url of the swf to the bin_debug_url context variable
And loads up the direct template djangoflash.html
Which, in djangoflash.html, includes the foo-debug.html wrapper for flash using the flash_template context variable
Which, in turn fills in the bin_debug_url context variable to point the foo.swf reference correctly to the thing you just compiled
Whew. :-P

"is_logged_in" templatetag does not render

for some reason, templatetags do not render in templates for django admin.
with this snippet from:
http://docs.djangoproject.com/en/dev/ref/templates/api/?from=olddocs#shortcut-for-simple-tags
{% if is_logged_in %}Thanks for logging in!{% else %}Please log in.{% endif %}
when placed in admin index.html, if a user is logged in, it shows "Please log in"
same with templatetags, can not get any app ones to show, do anything. there is no error/they do not get processed either
That's only an example, the is_logged_in variable is not actually defined in any templates unless you put it in the context.
If you added that line and got Please log in. it does mean that the tag is rendering. If it fails the if and goes to the else it is clearly being run. You need to find something in the template you can actually use for the if case, though. I haven't messed with the admin templates in newforms-admin, but depending if they use RequestContext and on which ContextProcessors you have enabled - you might be able to say {% if not request.user.is_anonymous %} ... or something similar.
I just tried this one:
request.user.is_authenticated
Right in the template and just worked as we wish!