0

I have started building a django project from the tutorial at https://docs.djangoproject.com/en/2.1/intro/tutorial01/

After finishing the base tutorial which creates a project with one app called "polls" I wanted to build a sort of home page that can hold many apps together. For this reason I built an app called "news" and now I'm looking at ways to compose the two apps together.

So far I'm doing so in the main 'news' template, which is called 'news/base.html' and I'm including the different apps in the code.

This is my 'news/base.html' file:

{% include 'news/index.html' %}
{% include polls_template %}
{% include 'news/footer.html' %}

The two templates 'news/index.html' and 'news/footer.html' are just html pages with no arguments, just for testing and they work fine.

The polls_template variable instead is a template variable that I create in the news.views.base function and pass to the template in the context.

This is the view snippet that does this:

def base(request):
    t = loader.get_template('polls/index.html')
    return render(request, 'news/base.html', {'polls_template': t})

The template is showing just fine but it shows an empty poll since there is no argument. Now my problem is that I cannot find a way to pass a context variable to this template object in order to fill it's fields.

I tried to do something like:

{% include polls_template with context=polls_context %}

But it does not work.

Ideally I would like a way to do all of that in the view because this would allow me to build the apps separately and then just use one view to gather them all and pass them to a template. Thanks in advance for any help!

  • Any template you include gets the same context variables as the template you include it in. So if your view adds the context variables required by your polls_template, then they will show up when you render them. i. e. in your view: `render(request, 'news/base.html', {'polls_template': t, 'poll': Poll.objects.first()}` will give you a `poll` object you can render in the template. – dirkgroten Oct 12 '18 at 16:43

1 Answers1

1

Possible duplicate of Django - two views, one page (disregard the references to Ajax.) One quick note: I see what you are trying to do, but you should understand that render() is a shortcut that includes both the template loading and the HttpResponse(). You don't need to call loader() if you are using render(). Another problem with your function, you've included the template within the context dict. Please read the linked post b/c there are a number of different approaches but for the sake of completeness, here's one way to approach what you are trying to do. First, typically you'd create a 'base.html' file that would be the container for your content, it would include header, footer and possibly the messaging templates. You could then extend the base.html and include other templates.

'base.html'

     <!doctype html>
     <html lang="en">
       <head>
        {% include 'header.html' %}
        <body>
        {% include 'news.html' %}

         {% block content %}
          //to be replaced by index/polls content that extends this template//
         {% endblock %}
         </body>
         {% include 'footer.html' %}
          </html>

'index.html'

    {% extends 'base.html' %}
     {% block content %}
      <ul>
     {% for question in questions%}
       <li> {{question}}</li>
      {% endfor %}
       </ul>
     {% endblock %}

'news.html'

     <ul>
     {% for article in news %}
       <li> {{article}}</li>
      {% endfor %}
       </ul>

And then your function

    def index(request):
         polls_questions = Question.objects.all()
         newest_articles = Articles.objects.filter(post=OuterRef('pk')).order_by('-created_at')
         return render(request, 'index.html', {'questions' : polls_questions, 'news': newest_articles})
chuck_sum
  • 113
  • 6