im doing something with feedparser: i have a templatetag for display "news" in my home page, but , how ill limit the feedparser result?
inclusion tag
from django.template import Template, Library
import feedparser
register = Library()
#register.inclusion_tag('rss_render.html')
def rss_render(object): #RSS URL "object"
rss = feedparser.parse(object)
return {'rss': rss}
template
<ul>
{% for r in rss.entries %}
<li> {{ r.title }}</li>
{% endfor %}
</ul>
Take this Django snippet for example.
You can use Django's slice template tag:
{% for r in rss.entries|slice:":10" %}
http://docs.djangoproject.com/en/dev/ref/templates/builtins/#slice
Related
I am trying to add a list of category tags in the sidebar of my Wagtail blog index page. The code below does work, but unfortunately it iterates through the posts and lists all the tags as individual tags, which I ultimately end up with duplicate tags. I built my blog from the Wagtail demo and since it doesn't use Views like I am used to, I am not sure where to add .distinct('tags').
Template
{% for b in blogs %}
{% for tag in b.tags.all %}
<li> <i class="glyphicon glyphicon-tag"></i> {{ tag }}<span>{{ tag }}</span>
{% if not forloop.last %} {% endif %}
</li>
{% endfor %}
{% endfor %}
Any logic that would normally go in a view function, can go in the page model's get_context method:
from django.contrib.contenttypes.models import ContentType
from taggit.models import Tag
class BlogIndex(Page):
# ...
def get_context(self, request):
context = super(BlogIndex, self).get_context(request)
blog_content_type = ContentType.objects.get_for_model(BlogPage)
context['tags'] = Tag.objects.filter(
taggit_taggeditem_items__content_type=blog_content_type
)
return context
(the tag-fetching code here is adapted from some internal Wagtail code.)
In this project I'm working with (I'm very new to Django), there are custom tags i.e. {{ custom_tag }} that a previous developer created.
In the HTML file, I find myself doing the following block of conditional logic many times in the same HTML file.
{% if custom_tag == "Blog Tag" %}
Blog
{% elif custom_tag == "About Tag" %}
About
{% else %}
etc...
{% endif %}
Are there ways that I can replace all of that conditional logic into something like {{ custom_tag|pretty }} or {{ pretty_custom_tag }}?
You can write your own criting a custom filter which would let you use {{ custom_tag|tag_pretty }}: https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
For example:
from django import template
from django.template.defaultfilters import stringfilter
register = template.Library()
#register.filter
#stringfilter
def pretty_tag(value):
return value.rpartition(" ")[0]
I have a number of templates that extend base.html. I want the base.html template to house my global navigation and have the text and links in the global navigation be based on a model Division (i.e. the CharField in the model will be used as the button text in the global nav, and the id will be used to build the URL). I thought tags might work, but what I end up with is this (yes, I'm new to Django and Python):
current_tags.py
from django import template
# Import your model
from libs.display.models import Division
from django.db import models
register = template.Library()
#register.simple_tag
def do_get_divisions(self):
d = Division.objects.all()
mylist = []
for each in d:
mylist.append(str(each.DivisionValue))
return my list
I'm attempting just getting the text value in each object to print at this point because I can't get or work with the objects in the template, as you'll see below.
base.html
<!DOCTYPE html>
<html>
<head>
{% load staticfiles %}
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}style.css" />
</head>
<body>
{% load current_tags %}
<p>{% do_get_divisions "" %}</p> **THIS ACTUALLY PRINTS mylist**
{% for each in do_get_divisions %} **THIS DOESN'T PRINT ANYTHING**
<p>{{ each }}</p>
{% endfor %}
{% block content %}
{% endblock %}
</body>
</html>
I'm sure there is a better way to do global nav based on a model in Django. I basically want to get all the Division objects and put them into a <ul> to use as my global nav in base.html. I am not that familiar with Django, but my views.py don't help me because I am rendering other templates, not base.html, which are extending base.html. For what it's worth, here's one views.py, where /display/info.html template extends base.html:
# Create your views here.
from django.http import HttpResponse
from apps.pulldata.models import Data
from django.shortcuts import render, get_object_or_404
from django.http import Http404
def info(request, group_id):
group = get_object_or_404(Data, pk=group_id)
s = group.XInGroup.all()
return render(request, 'display/info.html', {'Group': group, 's': s})
You cannot put a templatetag into another. Your for-loop is a templatetag that expects the name of an element in your context to iterate over.
If you want to handle the navigation in a template tag you should consider using inclusion tags.
Inclusion tags are functions that use templates to render their data.
A very basic implementation could look something like this:
tags.py
#register.inclusion_tag('navigation.html')
def navigation(selected_id=None):
return {
'navigation': Division.objects.all(),
'selected':selected_id,
}
In your templatetag file you create a dictionary with the navigation items and optionally the currentl selected item to highlight this navigation element.
navigation.html
<ul>
{% for item in navigation %}
<li{% if item.id == selected %} class="selected"{% endif %}>
{{ item.DivisionValue }}
</li>
{% endfor %}
</ul>
the navigation.html uses the dictionary from the python function as context so you start with simply iterating over the navigation.
base.html
{% navigation %}
or
{% navigation current_division.id %}
In the base.html you call the inclusion tag like a normal template tag. if you want to highlight the current item you add its id as a argument.
I'm trying to update an old Django project (last working at Django 1.4) to use class based generic views (In Django 1.5)
The following used to work
Template:
{% block content %}
{% for month in date_list %}
<h2>{{ month|date:"F" }}</h2>
<h2>Blah</h2>
{% endfor %}
{% endblock %}
urls.py
urlpatterns = patterns('django.views.generic.date_based',
...
(r'^(?P<year>\d{4})/$', 'archive_year', dict(entry_info_dict,make_object_list=True), 'coltrane_entry_archive_year'),
(r'^(?P<year>\d{4})/(?P<month>\w{3})/$', 'archive_month', entry_info_dict, 'coltrane_entry_archive_month'),
...
)
however when I updated the urls.py to use generic class
class ArticleYearArchiveView(YearArchiveView):
queryset = Entry.objects.all()
date_field = "pub_date"
make_object_list = True
allow_future = True
urlpatterns = patterns('',
...
url(
r'^(?P<year>\d{4})/$',
ArticleYearArchiveView.as_view(),
name='coltrane_entry_archive_year'
),
url(
r'^(?P<year>\d{4})/(?P<month>\w{3})/$',
dates.MonthArchiveView.as_view(
template_name='coltrane/entry_archive_month.html',
queryset=Entry.objects.filter(status=Entry.LIVE_STATUS),
date_field='pub_date'),
name="coltrane_entry_archive_month"
),
...
)
the following TemplateSyntaxError starts appearing:
Could not parse some characters: year|,month||date:"b"
I can render the template and check what's being passed to coltrane_entry_archive_month using the following:
{% for month in date_list %}
{{ year }}
{{ month|date:"b" }}
{% endfor %}
I did notice that {{ year }} is being rendered as 'Jan. 1, 2013' rather than '2013' that matches the regex in the url. This I don't understand.
Futher I then tried to render the following:
{% for month in date_list %}
{% url "coltrane_entry_archive_month" "2013","apr" %}
{% endfor %}
No joy, this time the TemplateSyntaxError is:
Could not parse the remainder: ',"apr"' from '"2013","apr"'
Both generic class views and the url seem to be largish topics in Django so any pointers would be very welcome indeed!
The url tag doesn't take comma-separated arguments, just list them with a space.
{% for month in date_list %}
{% url "coltrane_entry_archive_month" "2013" "apr" %}
{% endfor %}
which means you need to change your actual template to
{% url "coltrane_entry_archive_month" year month|date:"b" %}
Also just a note (which I noticed you followed in your second example)
Don’t forget to put quotes around the function path or pattern name!
Changed in Django 1.5: The first parameter used not to be quoted,
which was inconsistent with other template tags. Since Django 1.5, it
is evaluated according to the usual rules: it can be a quoted string
or a variable that will be looked up in the context.
I'm without clues on solving this problem.
I've a template tag that receives an Object:
{% score_for_object OBJECT_HERE as score2 %}
The problem is that I'm passing to the template a context that came from a raw select:
cursor = connection.cursor()
cursor.execute("select ...")
comments = utils.dictfetchall(cursor)
To solve the problem of the template tag that accepts a Django object, I've write a template tag:
'''
This template tag is used to transform a comment_id in an object to use in the django-voting app
'''
def retrive_comment_object(comment_id):
from myapp.apps.comments.models import MPTTComment
return MPTTComment.objects.get(id=comment_id)
With this template tag I expected this to work:
{% for item in comments %}
{% score_for_object item.comment_id|retrieve_comment_object as score2 %}
{{ score2.score }} {# expected to work, but not working #}
{% endfor %}
My question. It is possible to retrieve an object from a template tag?
Best Regards,
To get the score:
from django import template
from myapp.apps.comments.models import MPTTComment
register = template.Library()
#register.simple_tag
def retrive_comment_object(comment_id):
data = MPTTComment.objects.get(id=comment_id)
return data.score
{% for item in comments %}
Score: {% retrive_comment_object item.comment_id %}
{% endfor %}