I'm using Django 1.8.
I want to use a CharField with an internal context variable.
For example,
in models.py
...
content = models.CharField(max_length=200)
...
in template:
...
{{ model_instance.content }}
...
The output in html:
...
The content of a context variable is {{ request.variable }}
...
But I want to get:
...
The content of a context variable is test-test-test
...
How can I accomlpish it? I used {{ model_instance.content|safe }}, but it had no effect.
A simple template tag will do it:
yourapp/templatetags/yourapp_tags.py
from django.template import Template
#register.simple_tag(takes_context=True)
def render(context, content):
return Template(content).render(context)
yourapp/templates/template.html
{% load yourapp_tags %}
{% render model_instance.content %}
Just make sure your content fields are not writable for plain site users, as it imposes a security risk.
Related
I use this pattern:
class PersonAdmin(admin.ModelAdmin):
readonly_fields = ('address_report',)
def address_report(self, instance):
return format_html(...)
Source: docs about readonly_fields
Now I would like to use a custom templatetag in the Python method address_report().
What is the best way to call it?
I tried to called my templatetag directly, but this just returns a dictionary, not html.
I think you'll have to create a template from string. That way you can use any template tags or variables you want.
Example:
from django.template import Template, Context
def address_report(...):
# create template
t = Template("""
{% load custom_tag_module %}
<p>
Hello, {{ name }}! <br>
{% custom_tag %}
</p>
""")
# create context
c = Context({'name': 'World'})
# render template, mark safe and return
return mark_safe(t.render(c))
I have model LandingSnippet that contains attribute ...model = CharField()..., and it is related to context keyword (for example cars in context below)
I have next code in my view
def GeneratedLanding(request):
snippets = LandingSnippet.objects.all().filter(view_on=True).order_by('order')
context = {
'snippets':snippets,
...
'cars':Car.objects.all(), # this is cars
...
return render(request,'qlanding/generateindex.html',{'context':context})
how i can get querySet cars that is in context by keyword cars as a string
for example
{{context}}
prints
{'snippets': <QuerySet [<LandingSnippet: Snippet1Title>, <LandingSnippet: 2 - about - Лучшая служба развозки детей>]>, 'services': <QuerySet []>, 'cars': <QuerySet []>, 'faqs': <QuerySet []>}
and
{{snippet.model}}
prints
cars
QUESTION:
How can i get the {{ context.cars }} ? I think something like context[snippet.model] where snippet.model='cars'
i want push it inside another template when include
{% if snippet.module %}
{% with "qlanding/snippets/module/"|add:snippet.module|add:".html" as path %}
{% include path with model=context[snippet.model] %} # But this is incorect while rendering
{% endwith %}
{% endif %}
you can write a simple template tag like this:
first in your app directory create a directory named templatetags this directory must contains an empty file named __init__.py
create a file with any name in this directory. for example load_from_context
write these code on this file
from django import template
register = template.Library()
#register.tag(name="GetFromContext")
def get_from_context(parser, token):
bits = token.split_contents()
node_list = parser.parse(('endGetFromContext',))
variable = bits[1]
return GetFromContextNode(node_list, variable)
class GetFromContextNode(template.Node):
def __init__(self, node_list, variable):
self.node_list = node_list
self.variable = variable
def render(self, context):
variable_value = template.Variable(self.variable).resolve(context)
with context.push():
context['model'] = context.get(variable_value)
return self.node_list.render(context)
then in your template you can use it like this
{% load load_from_context %}
{# any code in your template #}
{% GetFromContext snippet.model %}
{% include path %}
{% endGetFromContext %}
#vorujack , I get the same error still. but based on your solution I got next.
from Django import template
register = template.Library()
#register.simple_tag
def get_model_from_context(context,model_name):
return context[model_name]
and how I used in view
{% get_model_from_context context=context model_name=snippet.model as model %}
{% include "qlanding/snippets/module/"|add:snippet.module|add:".html" with model=model %}
many thanks for #vorujack
I have a block as follows:
class SomeBlock(blocks.StructBlock):
choice = blocks.ChoiceBlock(choices=(('Y', 'Yellow'), ...))
# more fields
class Meta:
template = 'myapp/blocks/some_block.html'
In my template I have:
{% load wagtailcore_tags %}
<div>{{ value.choice }}</div>
This would display 'Y' as expected but how do I get it to display as 'Yellow'?
These variations do not work (get no output):
{{ value.get_choice_display }}
{{ value.bound_blocks.get_choice_display }}
Unfortunately there isn't a direct equivalent - Wagtail's blocks mechanism treats the display names as a detail that's specific to the edit form, rather than part of the data, so they're not easily accessible at the point where you're rendering the template. I'd suggest arranging things as follows:
Define the choice list in its own module where it can be imported from multiple places - e.g. myapp/colors.py:
COLORS = (('Y', 'Yellow'), ...)
COLORS_LOOKUP = dict(COLORS) # gives you a dict of the form {'Y': 'Yellow', ...}
Update the ChoiceBlock definition to refer to the list defined there:
from myapp.colors import COLORS
class SomeBlock(blocks.StructBlock):
choice = blocks.ChoiceBlock(choices=COLORS)
Create a custom template tag to do the lookup from value to display name - e.g. myapp/templatetags/color_tags.py:
from django import template
from myapp.colors import COLORS_LOOKUP
register = template.Library()
#register.simple_tag
def get_color_display_name(name):
return COLORS_LOOKUP.get(name)
Use this tag in your template:
{% load color_tags %}
...
{% get_color_display_name value.choice %} {# to output it immediately #}
{% get_color_display_name value.choice as label %} {# to assign it to the variable 'label' #}
I have this data that comes from a field in the database:
item_list = Links.objects.filter(visible=True)
In an iteration of item_list there is item.name and item.link. In item.link there could potentially be a string value of
'/app/user/{{user.id}}/'.
When rendering this particular item.link in a Django template, it comes out literally in html output as:
/app/user/{{user.id}}/
when literally I am hoping for it to render as:
/app/user/1/
Is there any way to force the template to recognize this as a compiled value for output?
You have to create a custom template tag:
from django import template
register = template.Library()
#register.simple_tag(takes_context=True)
def render(context, tpl_string):
t = template.Template(tpl_string)
return t.render(context)
And the in your template:
{% load my_tags %}
{% render item.link %}
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!