I'm using django flatpages, and I'm wondering if there is a concise way of loading one specific flatpage within a template. The docs show the following patterns:
{% load flatpages %}
{% get_flatpages '/about/' as about_pages %}
{% get_flatpages about_prefix as about_pages %}
{% get_flatpages '/about/' for someuser as about_pages %}
I just want to load one specific page in a template, essentially using it like an include statement (e.g. {% include 'homepage.html' %})
The approach I am using is this:
{% get_flatpages '/flat-homepage/' as flatpages %}
{{ flatpages.first.content|safe }}
This works fine, but I thought there might be a slightly neater way of doing this. I'm marking the content as safe as I want html styles to be applied (again, not sure if there is a better way of doing this)
By default, there are 2 solutions for that.
First, register your flatpage in urls as below:
from django.contrib.flatpages import views
urlpatterns = [
url(r'^about-us/$', views.flatpage, {'url': '/about-us/'}, name='about'),
]
That way, you can access it using {% url %} tag, like normal view.
Second way, if you know exact url of that page, you can access it's url using:
{% url 'django.contrib.flatpages.views.flatpage' url='url_to_flatpage_here' %}
There is no other way, because all flatpages are identified by url.
Related
I have taken a hint from this post
Customising tags in Django to filter posts in Post model
I have created the template tag but I am not sure how to use it in my html. I have a home.html where I want to show three featured post. I am looking for something like {% for post in featured_post %} and then show the post detail.
Also, do I necessarily need to create a featured_posts.html as in the above post because I don't want any extra page for the featured post. I just want them to add on my home page in addition to other stuff.
What I am trying to do is I have created a template tag as under
from django import template
register = template.Library()
#register.inclusion_tag('featured_posts.html')
def featured_posts(count=3):
if Post.is_featured:
featured_posts = Post.published.order_by('-publish')[:count]
return {'featured_posts': featured_posts}
The problem I am facing here is I can't import the Post model from model. My directory structure is somewhat like this:-
I have an app named posts.
Inside that I have models.py and templatetags module and inside the template tag I have blog_tags.py
I couldn't do the relative import.
And then created a new page featured_posts.html as under:-
<ul>
{% for post in featured_posts %}
<li>{{ post.title }} </li>
{% endfor %}
</ul>
Now, I want to use it in my home.html. How can I use it?
Edit:- As mentioned above I could load the models as under:-
from posts.models import Post
home.html
{% load blog_tags %}
{% featured_posts %}
Call your tag. That's it.
or
{% featured_posts count=15 %}
Note, featured_posts here is not the post list (which is iterated in for loop) from context but function name: def featured_posts(count=3). They have the same name in your code and probably this has confused you a little.
I have a common header used throughout the site. On some pages, based on the URI we're at, I'd like to include/exclude some html content. What would be the proper way to do it? I see a 'url' tag but that obviously isn't it (doesn't seem to work for me at all in fact, on Django 1.5.5). I was hoping for a simple filter, something like:
{% if url == '/dashboard/' %}
<!-- conditional html content -->
{% endif %}
I know that I could pass some custom data from the View action via its context, then check against it in the template, but that feels a bit.. excessive/iffy (?)
You can use request.path in the template to get the current url like so:
{% if request.path == '/dashboard/' %}
<!-- conditional html content -->
{% endif %}
For this to work you must have django.core.context_processors.request listed in your TEMPLATE_CONTEXT_PROCESSORS in your settings.py file.
How to do it "include tag" in jinja2. I need to output a block of articles in the base template. And they work in children.
views.py
Articles.query.filter_by(name=name).first()
base.html
{% block content %}
Content base
{% endblock %}
---{{ this_articles_tag }}----
children.html
{% extends 'base.html' %}
{% block content %}
Content children
{% endblock %}
---{{ output Articles }}----
Django in this "include tag", how to do it in jinja2? (Without using context_processor)
If you need to include another template in the template, just use include in Jinja. But if you are talking about template tags (in Django I remember I liked them a lot), then in Flask only your mentioned context_processor is the way to go. Which I think is not a bad thing at all.
Edit:
Easiest way to get context processor registered as a function is pointed in the documentation.
But if you want something more fancy, like dynamic loader or you will load your functrion from different places, then you can define your own decorator function, which basically wraps the function which returns dictionary:
def example_templatetag():
def get_something():
return get_want_you_want_from_db()
return dict(get_something=get_something)
Then where you create your Flask app object you can easily register this function:
app.context_processor(example_templatetag)
And then in a template you can use is like:
{% set data_you_wanted=get_something() %}
{{ data_you_wanted }}
But maybe for you the way mentioned in documentation will be more than enough ;)
When using Django templates, should I have some templates that act like "subroutines", so to speak, or should I generate HTML from within my code in these cases?
For example, I have a template with several lists of names, each of which I want to turn into a select. Should I have a template that renders the name_list variable into a select, and do something like this:
#in the view:
return {'name_list_1': name_list_1,
'name_list_2': name_list_2,
'name_list_3': name_list_3}
#in the template:
{% with name_list_1 as name_list %}
{% include "sub_name_list_select.html" %}
{% endwith %}
{% with name_list_2 as name_list %}
{% include "sub_name_list_select.html" %}
{% endwith %}
{% with name_list_3 as name_list %}
{% include "sub_name_list_select.html" %}
{% endwith %}
Or should I have a function in my code, name_list_to_select_html, which does the same job, and do this:
return {'name_list_1_html': name_list_to_select_html(name_list_1),
'name_list_2_html': name_list_to_select_html(name_list_2),
'name_list_3_html': name_list_to_select_html(name_list_3)}
#in the template:
{{ name_list_1_html|safe }}
{{ name_list_2_html|safe }}
{{ name_list_3_html|safe }}
Or are both of these wrong and I am getting the philosophy totally wrong?
Additional question: in terms of speed, is it slow to constantly include templates? Is that a bonus point for the in-code html generation?
Generally, HTML should only be generated in the templating system or directly related code. That keeps the view of the data completely separate from the business and functional logic. I feel that's a proper separation of concerns. Go with your first solution.
As for performance, Django should probably take around the same amount of time running either code. But it has built-in view and template fragment caching if you know those segments of code don't need to be regenerated on every request.
I have the following code in my template:
{% for req in user.requests_made_set.all %}
{% if not req.is_published %}
{{ req }}
{% endif %}
{% empty %}
No requests
{% endfor %}
If there are some requests but none has the is_published = True then how could I output a message (like "No requests") ?? I'd only like to use Django templates and not do it in my view!
Thanks
Even if this might be possible to achieve in the template, I (and probably many other people) would advise against it. To achieve this, you basically need to find out whether there are any objects in the database matching some criteria. That is certainly not something that belongs into a template.
Templates are intended to be used to define how stuff is displayed. The task you're solving is determining what stuff to display. This definitely belongs in a view and not a template.
If you want to avoid placing it in a view just because you want the information to appear on each page, regardless of the view, consider using a context processor which would add the required information to your template context automatically, or writing a template tag that would solve this for you.