Reputation: 1534
I'm not sure if it is variable or tag.
I have two apps (different styles, different navbars) but want to print the same document from db.
I created base.html, templates with extends and everything works perfectly. But.
The body of template is filled from database, which is a part of html code.
And in this code there's <p>The contact email is: [email protected]</p>
Of course this is wrong for secondapp.
I tried to change body with <p>The contact email is: {{ app_email }}</p>
, and set it with context
But it doesn't work - it prints
The contact email is: {{ app_email }}
template/document.html:
{% extends base %}
{% load crispy_forms_tags %}
{% load static %}
{% block head %}
<title>{{ title }}</title>
{% endblock %}
{% block content %}
<div class="container">
<div class="row justify-content-center">
<div class="col-9">
<h1 class="mt-2">{{ document.header }} !!!</h1>
<hr class="mt-0 mb-4">
{% autoescape off %}
{{ document.body }}
{% endautoescape %}
</div>
</div>
</div>
{% endblock %}
firstapp.views.py:
def myview(request):
context = {
'app_title' : 'First',
'title' : 'First - document',
'app_name' : 'first',
'app_email' : '[email protected]',
'document' : get_document('document1'),
'base' : 'first/base.html'
secondapp.views.py:
def myview(request):
context = {
'app_title' : 'Second',
'title' : 'Second - document',
'app_name' : 'second',
'app_email' : '[email protected]',
'document' : get_document('document1'),
'base' : 'second/base.html'
Is it possible this way? Mayby some filter?
edited: Now I know, that I have to prerender it in get_document. But how to pass unknown parameters?
This function works - but have to add sth do parameters (*args? **kwargs?) and redefine Context{{ *args? **kwargs?? }}
def get_document(name):
doc = Doc.objects.get(name=name)
doc.body = Template(doc.body).render(Context{{'app-email':'[email protected]'}})
return doc
Upvotes: 0
Views: 638
Reputation: 1089
The problem is you are treating the content of document1
in this case as a context variable itself. It never gets parsed by the django templating engine and so the {{ app_email }}
variable is never converted.
I see two options:
if the document is a file from disk (seems like that's not the case based on your description) then you need to figure out how to load the document into your template as another template. I know there are tags for loading another template based on the content of a variable. So you would pass template_name = "template/path/to/document"
in your view and then in your template include it with something like {% include template_name %}
. Actually, even if the template isn't on disk, you can write a template loader that loads it from where ever.
Alternatively, you can send the results of get_document(...)
through the template engine independently. So in the view.py you would render it separately before adding it to the template context. I think there used to be a django.shortcuts.render_string
function you could pass it through, though I think that might have changed in newer Django's. Update from OP: Template(<str>).render(<context>)
is the way to do it.
Upvotes: 2
Reputation: 1534
Thanks to @saquintes
def get_document(name,**kwargs):
doc = Doc.objects.get(name=name)
doc.body = Template(doc.body).render(Context(kwargs))
return doc
and in first.views.py:
(...)
def myview(request):
context = {
'app_title' : 'First',
'title' : 'First - document',
'app_name' : 'first',
'document' : get_document('document1', app_email = '[email protected]'),
'base' : 'first/base.html'
(...)
Upvotes: 0