Django TemplateSyntaxErrors in generic date based Class views - django

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.

Related

Data accessing & display in Django

I'm having trouble accessing database data in another template
different than django administration. In the administration page I
get results:
But when I try to display them in another template:
(No results available)
Here's how my urls.py admin page and template urls looks like:
urlpatterns = [
path('admin/', admin.site.urls),
path('lista/', views.entitats, name = 'lista_entitats')
]
Here's how my admin.py call to entity list and register looks like:
class EntitatAdmin(admin.ModelAdmin):
list_display = ('codi', 'nom', 'adreça', 'cp', 'correu', 'inspector')
inlines = [DiaLliureDisposicioInline, VisitesDirectorCentreInline, ExitEscolarInline, ObresCentreInline, OfertaEstudisInline, NEE_alumnatInline, FormacioInline, ProjectesInline, ProfessorsInline, DespesesFuncionamentInline]
search_fields=('nom',)
list_per_page=5
admin.site.register(Entitat, EntitatAdmin)
In my views.py this is how I ask for the template (and where I feel I'm not getting db information well):
from entitats.models import Entitat
def entitats(request):
lista_entitats = Entitat.objects.all()
context = {'llista_entitats': lista_entitats}
return render(request, 'entitats.html', context)
And finally my template, where I try to display the list of entities:
{% if context.llista_entitats %}
<ul>
{% for question in objects_list %}
<li>{{ question.question_text }}</li>
{% endfor %}
</ul>
{% else %}
<p>Ninguna entidad disponible.</p>
{% endif %}
Sorry if it's loong, I'll delete if there's something not necessary, and THANKYOU in advance.
You don't need context.variable_name syntax in template to check variable value, just use:
{% if llista_entitats %}
instead of
{% if context.llista_entitats %}
Also since your variable is llista_entitats it should be:
{% for question in llista_entitats %}
<li>{{ question.question_text }}</li>
{% endfor %}
Note I replaced objects_list with llista_entitats and entitat.id with question.id.

Django : filter Datefield in template

I'm using Django 1.5.8
I'd like to filter Datefield type data in template like following code.
express with timesince format for recent articles
express with date format for old articles
some_template.html
{% for article in articles %}
{# recent articles #}
{% if article.created >= (now - 7 days) %}
{{ article.created|timesince }}
{# old articles more than one week past #}
{% else %}
{{ article.created|date:"m d" }}
{% endif %}
{% endfor %}
Is there a solution to handle {% if article.created >= (now - 7 days) %} by django's own template tags?
Or do I have to make new custom filter?
Although I'm sure it's possible to do this with a custom template tag, I think you'll find it is a lot easier to implement this test in your model code. For example:
from datetime import date, timedelta
class Article(models.Model):
[...]
def is_recent(self):
return self.created >= date.today() - timedelta(days=7)
Then your template can be:
{% for article in articles %}
{% if article.is_recent %}
{{ article.created|timesince }}
{% else %}
{{ article.created|date:"m d" }}
{% endif %}
{% endfor %}

Combine built-in tags in templates with variables

I want to combine the built-in tag: {% url %} with a dynamic url which I parse with {{ url_value }}
I tried doing: {% url 'urlname' url_value %}, but it didn't work
This is the url:
url(r'^(?P<slug>[^/]+)/$', 'reviews.views.single_product', name='product_detail'),
{{url_value }} just represents the slug
I think it should be like:
{% url product_detail slug=url_value %}

Reference a url with an id by name in Django

I want to reference a dynamic url in my templates using its name, but am not sure how to incorporate the object id. In other words, I want to reference "/products/98" in my template without having to hard code it (as my url patterns might change).
In my urls.py, I have:
url(r'^products/(\d+)/$', 'products.views.show_product', name='product'),
How do I name my pattern such that I can call {% url ??? %} in the template to get the correct item with a specified id. e.g.
{% for product in product_list %}
Product #{% product.id %}
{% endfor %}
Use {% url product product.id %}.
urls.py:
url(r'^products/(?P<product_id>\d+)/$', 'products.views.show_product', name='product'),
template:
{% load url from future %}
{% for product in product_list %}
Product #{{ product.id }}
{% endfor %}
Make sure your products.views.show_product view function takes product_id as a parameter.

django feedparser limit the result

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