Django 1.8: cannot present a List of my blog entries on my site

Question!

I have been trying to build my Django blog page, by somehow querying the posts I made in counter-chronological order. So far I made three test posts (labeled 'Test Entry' 1-3), but after I tried to present the posts in a query list, I came across a Template error (resolved), then in its place is a type error (resolved), and now I have a equally tedious issue: a blank webpage. Right now I simply cannot get my posts on the actual webpage.

Here's what I got:

models.py

from django.db import models
from django.db.models import permalink
from django_markdown.models import MarkdownField

# Create your models here.

class EntryQuerySet(models.QuerySet):
    # This will be used for filtering everything that is published
    def published(self):
        return self.filter(publish=True)

class Post(models.Model):
    title = models.CharField(max_length=200) 
    body = MarkdownField() # formerly Text Field
    slug = models.SlugField(max_length=200, unique=True)
    publish = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True) # Keeps track of everytime it gets saved
   # author = models.ForeignKey(User)
    # tags = models.ManyToManyField(Tag) # 16 min vid

    objects = EntryQuerySet.as_manager() #Im allowed to do this because of the QuerySet class

    def __str__(self): 
        return self.title

    @permalink
    def get_absolute_url(self):
        return ('view_blog_post', None, { 'slug': self.slug })

    class Meta:
        verbose_name = "Blog Entry"
        verbose_name_plural = "Blog Entries"
        ordering = ["-created",]

views.py:

from django.shortcuts import render 
from . import models # so I can import 'Post'
from django.views.generic.list import ListView 
from django.utils import timezone

class BlogIndex(ListView): 
    model = models.Post
    def get_queryset(self, request):
        template_name = "blog.html"
        posts = models.Post.objects.filter(publish=timezone.now()).order_by('publish')
        return render(request,template_name,{'posts': posts})

base.html

<!DOCTYPE html>
<html lang="en">
  <head>
    {% include 'header.html' %}
  </head>

  <body>
  <!-- Navbar -->
    {% include 'navbar.html' %}

  <!-- Jumbotron -->
   {% block jumbotron_content %}

   {% endblock %}

  <!-- Container -->
    <div class="container">

      {% block content %}
      {% endblock %}

      {% block blog_entries %}
      {% endblock %}
   </div>


  <!-- FOOTER -->
      <footer>
        <p>&copy; Company 2014</p>
      </footer>
    </div> <!-- /container -->
    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="http://getbootstrap.com/dist/js/bootstrap.min.js"></script>
    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
    <script src="http://getbootstrap.com/assets/js/ie10-viewport-bug-workaround.js"></script>
  </body>
</html>

blog.html

{% extends "base.html" %}
{% load django_markdown %}

{% block blog_entries %}
<div id="block">
<div class="prose"> 
<h1>Articles</h1>
    {% if posts %}
        <ul>
            {% for post in posts %}
                <li>
                <a href="{{ post.get_absolute_url }}"> 
                {{ post.title }}
                </a> 
                </li>
            {% endfor %}
        </ul>
    {% else %}
        <p>There are no posts...but there should BE!</p>
    {% endif %}
</div>
</div>
{% endblock %}

urls.py

from django.conf.urls import include, url
from django.contrib import admin
from blog.views import BlogIndex

url1 = url(r'^admin/', include(admin.site.urls))           # 1. url for "admin" page
url2 = url(r'^$', 'joins.views.home', name='home')         # 2. url for "home" page
url3 = url(r'^blogI/$', BlogIndex.as_view(), name="index") # 3. url for the "blog" page
url4 = url(r'^markdown/', include('django_markdown.urls')) # 4. url for the "django_markdown" module

urlpatterns = [url1, url2 , url3 ,url4]

and here's my general working environment:

Request Method: GET
Request URL: http://127.0.0.1:8000/blogI/

Django Version: 1.8
Python Version: 3.4.3
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'joins',
 'blog',
 'django_markdown')

Has anyone actually come across this issue, especially if while using Python 3.4 and Django 1.8? For all I know my issue fairly simple and Im not programming this right. Is there something wrong with my 'blog.html' file? What about my BlogIndex class in my 'views' file? I have been suspecting my BlogIndex function is coded wrong, but if that is fine then its probably my 'blog' template thats not right; maybe its both. Any kind of help is progress for me, at this point. Thanks.



Answers

EDIT: The syntax for render is

render(request, template_name, context)

You have not mentioned request in your render statement. try:

return render(request, template_name,{'posts': posts})


The method get_queryset should simply return a queryset, you shouldn't be rendering a template there, or returning a dictionary.

Try something like the following.

class BlogIndex(ListView): 
    model = models.Post
    template_name = "blog.html"
        def get_queryset(self):
            return models.Post.objects.filter(publish=timezone.now()).order_by('publish')

In your template, iterate through post_list instead of posts.

{% for post in posts %}

Finally, you could simplify your templates by overriding the content block in your blog.html, then removing the blog_entries block from the base template.

By : Alasdair


You are getting the error get_queryset() missing 1 required positional argument: 'request' because you have defined request as a parameter in your get_queryset() method but in actual Django code's get_queryset(), request is not an argument for it. Just remove request as an argument from get_queryset() and it should work.

Also, you need to return a queryset in get_queryset() method and not do all the rendering and stuff there. The purpose of get_queryset is to return a queryset only.

Final code should be:

from django.shortcuts import render 
from . import models # so I can import 'Post'
from django.views.generic.list import ListView 
from django.utils import timezone

class BlogIndex(ListView): 

    model = models.Post
    template_name = "blog.html"

    def get_queryset(self):
        return models.Post.objects.filter(publish=timezone.now()).order_by('publish')


This video can help you solving your question :)
By: admin