Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python

[Django] Basic query – I'm not seeing the problem

I'm trying to make a simple page that queries the latest news from another app's model.

news/models.py

from django.db import models


class News(models.Model):
    title = models.CharField(max_length=250)
    text = models.TextField(blank=True)
    date = models.DateField()

Here are my querysets.

home/views.py

from django.shortcuts import render

from news.models import News

from .models import Index


def index(request):
    index = Index.objects.all()
    context = {'index': index}
    return render(request, 'home/index.html', context)


def news(request):
    latest_news = News.objects.order_by('-date')[:5]
    context = {'latest_news': latest_news}
    return render(request, 'home/index.html', context)

And finally the home/templates/home/index.html

{% extends 'base.html' %}
{% load md2 %}

{% block content %}
  {% for index in index %}
    <h1>{{ index.title }}</h1>
    {{ index.text|markdown }}
  {% endfor %}
{% endblock %}

{% block sidebar %}
<h3>News</h3>
  {% for news in latest_news %}
    {{ news.title }}
    {{ news.date }}
    {{ news.text }}
  {% endfor %}
{% endblock %}

When I render the page in the browser no news are coming through. Is my context wrong?

3 Answers

Chris Howell
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Chris Howell
Python Web Development Techdegree Graduate 49,702 Points

Hi csj

So taking your code as example...

For http://127.0.0.1:8000/indexnews/

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^$', views.index), # views.index is calling the 'def index()' function in views.py
    url(r'^$', views.news) # views.new is calling the 'def news()' function in views.py

    # These routes are conflicting so Django may get confused.
]

You could try this...

UPDATED

views.py

from django.shortcuts import render

from news.models import News

from .models import Index


def index(request):
    index = Index.objects.all()
    latest_news = News.objects.order_by('-date')[:5]
    context = {'index': index, 'latest_news': latest_news}
    return render(request, 'home/index.html', context)

# urls.py points to this news function
# for the route "indexnews/"
def news(request):
    index = Index.objects.all()
    latest_news = News.objects.order_by('-date')[:5]
    context = {'index': index, 'latest_news': latest_news} # context gets your querysets in your template
    return render(request, 'home/index.html', context)

UPDATED

urls.py

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^$', views.index),
    url(r'^indexnews/$', views.news)
]

See if that works, and let me know if you understand why :)

Chris Howell
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Chris Howell
Python Web Development Techdegree Graduate 49,702 Points

Hey csg,

Is it possible that you are making a request to a route that is calling only the def index function? Because that would explain why you are not getting the latest_news context passed in? Since they are both using the same index.html template the only time latest_news context is passed in is when the def news function is called.

Hi Chris, I'm not sure exactly what you are saying, so therefore it is most likely the case that it is where the mistake is.

In my home/urls.py currently looks like this:

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^$', views.index)
]

But if I add another template, like indexnews.html and edit the news view function to use that template instead:

def news(request):
    latest_news = News.objects.order_by('-date')[:5]
    context = {'latest_news': latest_news}
    return render(request, 'home/indexnews.html', context)

and add the view to the urls.py:

urlpatterns = [
    url(r'^$', views.index),
    url(r'^indexnews/$', views.news)
]

Pointing the browser to http://127.0.0.1:8000/indexnews/ the news are rendered. But how to I pass both things into the same template?

Thanks Chris! You didn't miss anything, I think I updated the edit while you were writing. I fixed the issue using class based views instead. Sorry for wasting your time.

class Index(ListView):
    model = Index

    def get_context_data(self, **kwargs):
        context = super(Index, self).get_context_data(**kwargs)
        context['news'] = News.objects.all()
        return context