I am trying to load some HTML element in my django template, if a specific app is defined in my settings.py file. But it doesn't work. The if statement behaves like the app doesn't exist:
{% if 'myapp.edit_data' in INSTALLED_APPS %}
<p> dfsdfsdf </p>
{% endif %}
I also tried with other apps and I get the same behavior. What am I missing?
You can't automatically access settings like INSTALLED_APPS in the template. You have to add it to the template context.
For example, in the view, you could do:
from django.conf import settings
def my_view(request):
return render(request, 'my_template.html', {'INSTALLED_APPS': settings.INSTALLED_APPS})
If this check was in the base template, then you might want to create a template context processor instead of changing every view.
Related
In my Django project, I have created a custom admin page for an app via the get_urls() method. I'd like to add a link to the app's main model index view that will take users to this custom page - however, I'm having some trouble creating this link element correctly and I don't seem to be able to piece together the right way to do it - I'm just left with a Reverse for 'export' not found. 'export' is not a valid view function or pattern name. error.
I've set up the admin for the app like so:
# my_project/observations/admin.py
from django.template.response import TemplateResponse
from django.urls import path
class ObservationAdmin(SimpleHistoryAdmin, SoftDeletionModelAdmin):
change_list_template = 'export_link.html'
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path('export/', self.admin_site.admin_view(self.export_view), name='export')
]
return custom_urls + urls
def export_view(self, request):
context = dict(
self.admin_site.each_context(request),
)
return TemplateResponse(request, 'export.html', context)
and the two templates that are referenced:
# my_project/observations/templates/export.html
{% extends "admin/base_site.html" %}
{% block content %}
<div>
Some custom content
</div>
{% endblock %}
# my_project/observations/templates/export_link.html
{% extends 'admin/change_list.html' %}
{% block object-tools-items %}
<li>
Export
</li>
{{ block.super }}
{% endblock %}
Navigating directly to http://localhost:8000/admin/observations/observation/export/ works perfectly, I see the custom content page exactly as I want it... so the issue I'm striking is with the link template - I get the Reverse... error when I navigate to the model index page.
Perhaps the argument I'm passing to url is incorrect, or I need to register that URL elsewhere - but I don't quite know. The other examples of link elements like this that I've been able to find don't reference URLs created via the admin class' get_urls() method - so any guidance on this would be greatly appreciated.
Thanks very much, let me know if there's any other info that I can provide to help sort this out.
I think the problems is in missing namespace in your export_link.html template. Instead of:
Export
try:
Export
So I often have to use something like the following in my Django templates:
{% include "conname.html" %}
I'd like to be able to instead just have my own tag and only have to type something like
{% conname %}
Is there an easy way to setup some sort of alias so that when ever the template engine sees the conname tag it knows that should actually be a specific include tag?
Pretty simple, in a module just add the following code (mine are usually called custom_tags.py:
from django import template
register = template.Library()
#register.simple_tag
def conname():
return '''{% include "conname.html" %}'''
#to make it available everywhere (i generally add this to my urls.py
from django.template.loader import add_to_builtins
#this will be aded to all templates
add_to_builtins('custom_tags')
In your template you would just use {% conname %}
Or you could make it more complicated and programatically call IncludeNode but that is overkill.
I'm trying to create inclusion tag and place it on the page but it's not work.
My views.py:
from django.shortcuts import render_to_response, redirect
from django import template
register = template.Library()
#register.inclusion_tag('weather.html')
def weather():
return {'city': 'angola'}
def home(request):
return render_to_response('index.html')
index.html
<title> TITLE </title>
Hi everyone!
{% weather %}
weather.html
weather is fine in {{city}}
Django debug page says that "Invalid block tag: 'weather'" so I guess I put declaration of inclusion_tag in wrong place? Where I need to put it to get it work?
Template tags need to go in a module in your app's templatetags directory. See the code layout section of the custom template tag docs for full details.
You then have to load your tag library in the template before you use your tag.
{% load my_tags %}
{% weather %}
I am trying to put a login form in every page in my web that uses django.contrib.auth.views.login. I created a templatetag in templatetags/mytags.py, where I define a function called get_login wich looks like this:
#register.inclusion_tag('registration/login.html', takes_context=True)
def get_login(context):
...
return {'formLogin': mark_safe(AuthenticationForm())}
...and in base.html:
{% load mytags %}{% get_login %}
The problem now is that the template (registration/login.html) doesnt recognize {{ formLogin.username }},{{ formLogin.password }}... and so on.
What am I missing?
mark_safe returns an instance of django.utils.safestring.SafeString, not a form, so those lookups will fail. I don't think there's anything wrong with directly returning the form (that's what all the generic views in django.contrib.auth do when populating templates, for instance). Just change your return statement to
return {'formLogin': AuthenticationForm()}
and it should work.
I'm trying to use WTForms with Django & a MongoEngine/MongoDB database backend. The forms are outputting properly, but I can't for the life of me get the labels to show up.
Here is my template code:
{% load wtforms %}
<form>
{% for f in form %}
{{ f.label }}: {% form_field f %}<br/>
{% endfor %}
</form>
This is what I am passing in the view:
form = StrandForm()
return render_to_response('create_strand.html', locals(), context_instance = RequestContext(request))
The StrandForm class I have tried both creating from the WTForm mongoengine extension's model_form class, and from WTForm's Form class. The label exists in the view, I can print it to the console and it shows the rendered form label, but somehow it gets lost when transferring to the template. Am I doing something wrong?
Django 1.4 has a new feature: do_not_call_in_templates attribute.
If you set it on wtforms.Field class, every child class inherits and all fields will work fine in django templates.
import wtforms
wtforms.Field.do_not_call_in_templates = True
Now following code works as expected:
{% load wtforms %}
{{ f.label }}: {% form_field f %}
I encountered the same problem today. It has to do with the way WTForms is programmed so that it will work with many different templating libraries. Django 1.3 will only see f as it's HTML string even though it has other attributes.
In order to fix this you must add a template tag to retrieve the attribute.
Add the following to your projects hierarchy:
templatetags
templatetags / init.py
templatetags / templatetags
templatetags / templatetags / init.py
templatetags / templatetags / getattribute.py
Then in your settings.py file, add the following line to INSTALLED_APPS
'templatetags',
Open up getattribute.py and paste the following code:
from django import template
from django.conf import settings
register = template.Library()
#register.tag
def getattribute(parser, token):
try:
tag_name, tag_object, tag_function = token.split_contents()
except ValueError:
raise template.TemplateSyntaxError("%r tag requires two arguments" % token.contents.split()[0])
return getattrNode(tag_object, tag_function)
class getattrNode(template.Node):
def __init__(self, tag_object, tag_function):
self.tag_object = tag_object
self.tag_function = tag_function
def render(self, context):
return getattr(context[self.tag_object], self.tag_function)()
This will allow you to use the follow code whenever you're inside a template and need an attribute that won't show up:
{% load getattribute %}
{% getattribute OBJECT ATTRIBUTE %}
In your case:
{% getattribute f label %}
Hope that helped!