Harry Whitnear
Harry Whitnear

Reputation: 189

The view blog.views.BlogViews didn't return an HttpResponse object. It returned None instead

I'm having a problem with the views for my blog main page. I've read a lot of problems with the same error but couldn't find a solution that i thought matched with my problem.

I am trying to emulate my old code with a new View so that i can customise it further in the future.

  path('', ListView.as_view(
                    queryset=Post.objects.filter(posted_date__lte=now).order_by("-posted_date")[:25],
                    template_name="blog/blog.html")),

i was previously using just the above url pattern to display my blog posts but im moving to a view:

def BlogViews(TemplateView):
  def get(self, request):
    posts = Post.objects.all().order_by("-posted_date")[:25]
    args = {
      'posts' : posts,
    }
    return render(request, 'blog/blog.html', args)

and the new url

path('', BlogViews, name='blog'),

However this view is not working and returns the error in the title. I'm importing TemplateView, Post and render correctly i believe.

Upvotes: 0

Views: 69

Answers (1)

Alasdair
Alasdair

Reputation: 309029

TemplateView is a class-based-view, so you subclass it with class.

class BlogViews(TemplateView):
    def get(self, request):
        posts = Post.objects.all().order_by("-posted_date")[:25]
        args = {
            'posts' : posts,
        }
        return render(request, 'blog/blog.html', args)

Then use .as_view() in the URL pattern.

path('', BlogViews.as_view(), name='blog'),

Avoid overriding get or post for class-based views. You end up losing the functionality of the parent class or duplicating it. You can take your ListView.as_view(...) as the starting point for the view, for example:

class BlogView(ListView):
    template_name="blog/blog.html"

    def get_queryset(self):
        # Use get_queryset instead of queryset because you want timezone.now()
        # to be called when the view runs, not when the server starts 
        return Post.objects.filter(posted_date__lte=timezone.now()).order_by("-posted_date")[:25]

In your case, it might be easier to use a function-based-view:

def blog_view(request):
    posts = Post.objects.all().order_by("-posted_date")[:25]
    args = {
        'posts' : posts,
    }
    return render(request, 'blog/blog.html', args)

Then include it in the URLs with:

path('', blog_view, name='blog'),

Upvotes: 1

Related Questions