Daniel Gizzi
Daniel Gizzi

Reputation: 13

Iterating over a model in Django template not rendering anything

Problem:

I am trying to simply iterate over my Category model and display a list of categories. I've successfully done so with posts, but for some reason I can't get it to work with my categories model (It doesn't even make it passed the {% if categories %} statement). Thus, the <h2>Categories:</h2> and below is not rendered at all.

I currently have two categories in my database ('Fitness' and 'Nutrition'). They are in my admin, and they also show up when I query through the command line. I can also successfully link to them from my 'post_detail' page (and display all posts within a category). However, I can't seem to iterate over the model to display all categories as a list...

Code:

post_list.html

<div class="container">
  <h2>Categories:</h2>
    {% if categories %}
    <h2>Categories</h2>
    <ul>
      {% for category in categories %}
        <li>{{ category.name }}</li>
      {% endfor %}
    </ul>
    {% endif %}
</div>

models.py

from django.db import models
from django.utils import timezone
from django.template.defaultfilters import slugify

class Category(models.Model):
    name = models.CharField(max_length=255, blank=False, default='')
    slug = models.SlugField(max_length=100, default='', unique=True)


    class Meta:
        verbose_name = "Category"
        verbose_name_plural = "Categories"
        ordering = ['name']

    def __str__(self):
        return self.name

    def __unicode__(self):
        return self.name

views.py

from .models import Post, Category
from .forms import PostForm
from django.shortcuts import redirect
from django.db.models import Count


def category_detail( request, slug ):
    category = get_object_or_404( Category, slug= slug )

    context = {
        'category': category,
        'posts': category.post_set.all()
    }

    return render( request,'blog/category_detail.html', context )

def post_list(request):
    posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
    context = {
        'categories': getSortedCategories()
    }
    return render(request, 'blog/post_list.html', {'posts': posts})

urls.py

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.post_list, name='post_list'),
    url(r'^(?P<slug>[-\w]+)/$', views.category_detail, name='category_detail'),
    url(r'^post/(?P<pk>\d+)-(?P<slug>[-\w]+)/$', views.post_detail, name='post_detail'),
    url(r'^post/new/$', views.post_new, name='post_new'),
    url(r'^post/(?P<pk>\d+)/edit/$', views.post_edit, name='post_edit'),
]

Upvotes: 1

Views: 446

Answers (1)

devxplorer
devxplorer

Reputation: 637

You do not transmit categories in the template context, you need to rewrite return expression like this:

return render(request, 'blog/post_list.html', {'posts': posts, 'categories': getSortedCategories()})

Upvotes: 3

Related Questions