I currently have a function called "copyright" (a dynamic copyright message) that I am trying to include into my base Django template, like below:
def copyright():
some code
some more code
print(finaloutput)
I have it sitting in my modules/utils.py which is in my assets directory which I have registered in my static directories.
I want to be able to call that function like {{ copyright }} straight in my top level base.html inside my main templates folder.
I have tried everything to ensure I am loading the staticfiles with no luck. Am I approaching this the wrong way?
Unfortunately almost everything you're doing here is wrong.
This has nothing to do with static files: as you said yourself, this is a dynamic function so isn't static by definition. Anyway, you can't put Python code in your assets directory. And finally, any function like this will always need to return the result, not print it.
What you need here is a template tag, which you put in your app's templatetags directory and register via the decorator:
#register.simple_tag
def copyright():
some code
some more code
return finaloutput
Then, load the tags in your template and call it as a tag, not a variable:
{% load utils %} # or whatever you called the file
...
{% copyright %}
See the template tags docs.
There are several ways to achieve your end goal, but nothing you are doing will get you there.
You can,
Use template tags.
Use context processors, in several different ways.
Use {{ view.function_name }} as-is in your templates if you are using class based generic views from Django.
Judging from how I think you have things set up, the fastest way could be to just pass in some context data in your views.
If you are using functional views, your code can look something like this:
def my_view(request):
def copyright():
return "copyright 2018"
return render('my_template.html', {'copyright': copyright})
If you are using class based generic views, you can simply modify your get_context_data.
class Home(TemplateView):
def get_context_data(self, *args, **kwargs):
ctx = super(TemplateView, self).get_context_data(self, *args, **kwargs)
ctx['copyright'] = self.copyright()
return ctx
def copyright(self):
return "copyright 2018"
Related
I have an API which gives me a list of movies, and there images are in HTTP links like:
https://d2gx0xinochgze.cloudfront.net/5/public/public/system/posters/12/thumb/Tevar-Movie-Opening-Day-Box-Office-Collection-Report-1140x752_1482917123.jpg
So in django we use static file {% static 'image.jpg' %} to display images in templates, But how to display api images links in template?
{% static 'image.jpg' %} doesn't magically make the image show up in the website, django renders the template with what its been given. Static means take a look at the statics folder, search for the given parameter as a file, and get the url for that given static asset.
In your particular case, you say you get the url of the images. You can easily add those urls to context, which is then gonna be a part of the rendering process.
For a function view it would roughly look like this.
def view(request, *a, **kw):
template = loader.get_template('my_template.html')
context = {'my_image': get_image_from_api()}
return HttpResponse(template.render(context, request))
For a class based view it would roughly look like this.
class MyView(TemplateView):
template_name = 'my_template.html'
def get_extra_context(self):
_super_context = super().get_extra_context()
context = {'my_image': get_image_from_api()}
return {**_super_context, **context}
For both of these views, which are roughly the same; you now can use {{my_image}} inside the template to refer to the url. Hope it helps!
Fetch the images via python in views per say. Pass them through your context when rendering the page. Use django's template tags to put the URLs within tags.
I'm trying NOT to write same code twice on different templates. Real hassle when changing something.
So when I go to a section of the webpage, I want to display a side menu. This side-menu is suppose to be on several templates. Like index.html, detail.html, manage.html and so on.
But the section is only a part of the webpage, so I can't have it in base.html.
I was thinking about using include. But since the side menu is dependent of DB queries to be generated, I then have to do queries for each view. Which also makes redundant code.
What is best practice for this feature?
Cheers!
You could write custom inclusion_tag, that's more feasible for the scenario:
my_app/templatetags/my_app_tags.py
from django import template
register = template.Library()
#register.inclusion_tag('side_menu.html')
def side_menu(*args, **kwargs):
# prepare context here for `side_menu.html`
ctx = {}
return ctx
Then in any template you want to include side menu do this:
{% load side_menu from my_app_tags %}
{% side_menu %}
<p>Hello, my name is {{ name }} ! </p>
Where/how do I set the variable: name = 'mike'? I've tried putting this in the settings.py and models.py file and it does not work.
Any info of proper code to put in a .py file would be great! I've searched through the docs page but didn't see how to set a variable for retrieval.
You need to set your variable value in the view function which normally put in view.py
e.g.
def hello(request):
return render(request, "hello.html", {"name": "mike"})
And you may would like to check https://docs.djangoproject.com/en/dev/topics/http/shortcuts/#render to find more about how to render templates with passed variables.
You need also learn more about how does Django's URL mapping works https://docs.djangoproject.com/en/dev/ref/urls/
Use context processors in django. Django handles this dilemma of making some information available to
all pages with something called context processors.
Some Code is like this,
Create a new file called context_processors.py inside your utils app directory, and add the
following code to it:
from project import settings
def context_data(request):
return {
'name': settings.name,
'request': request
}
I want to create a reusable template (almost like a UserControl from the .NET world) that I can apply in multiple places, something like:
{% for thing in things %}
{% render_thing thing %}
{% endfor %}
Where render_thing is my custom inclusion tag. My Python code reads as follows:
def get_full_path(relative_path):
return os.path.join(os.path.dirname(__file__), relative_path)
def render_thing(thing):
return {'thing':thing }
register = template.create_template_register()
register.inclusion_tag(get_full_path('thing.html'))(render_thing)
Where thing.html is my little template. However, when I run this I get the error:
TemplateSyntaxError: Invalid block tag: 'render_thing'
What am I missing?
If you are using Django 1.2 templates, you will need to supply a Python module-style reference to your custom tag code rather than a file path.
There's a full description of the problem and the solution on my blog.
EDIT:
Sorry to be so high-level on you. Here's a more step-by-step explanation:
Put your custom tag code in a file, say my_custom_tags.py for the sake of example.
take the .py file that your custom tag code lives in and put it in a subdirectory of your main AppEngine project directory, say customtags for the sake of an example.
in that new subdirectory, create an empty file that has the name __init__.py
in your AppEngine application's main .py file, add this code:
from google.appengine.ext.webapp import template
template.register_template_library('customtags.my_custom_tags')
All of the custom tags defined in your custom tag library should now be available in your template files with no additional work.
load template tag
{% load my_template_library %}
see manual
http://docs.djangoproject.com/en/dev/howto/custom-template-tags/
http://www.mechanicalgirl.com/view/custom-template-tags-in-django/
http://www.protocolostomy.com/2009/08/05/practial-django-projects-custom-template-tags-and-updates-on-linuxlaboratory/
You need to load the templatetag library within each template that uses it.
{% load my_template_library %}
In one of my Django templates, I have a chunk of HTML which repeats at several places in the page. Is there a way I could use another template for this chunk alone and "instantiate" the template where required?
You need to read about template inheritance.
Or you can use template composition.
Inheritance is, generally, a better way to go.
I've met the same issue some time ago and here is what I got.
Seems like it's not really well documented, but there is quite obvious solution - insert HTML blocks in your main template and then pass the result of the other template render there.
Example:
In main template (app/main.html):
<!-- ... -->
{% autoescape on %}
{{html}}
{% autoescape off %}
<!-- ... -->
In view code:
from django.template.loader import get_template
def my_view(request, ...):
# Do stuff...
context = {'data': 'data'}
t = get_template('app/partial_template.html')
html = t.render(context=context)
return render(request, 'app/main.html', context={'html': html, 'rest_data': 123})
Thus you'll get some template rendered inside another template with perfect separation of concerns (parent template doesn't know anything about child's context nor about child itself).