2

this is probably a question for absolute beginners since i'm fairly new to progrmaming. I've searched for couple of hours for an adequate solution, i don't know what else to do.

Following problem. I want to have a view that displays. e.g. the 5 latest entries & 5 newest to my database (just an example)

#views.py
import core.models as coremodels

class LandingView(TemplateView):
    template_name = "base/index.html"

    def index_filtered(request):
        last_ones = coremodels.Startup.objects.all().order_by('-id')[:5]
        first_ones = coremodels.Startup.objects.all().order_by('id')[:5]
        return render_to_response("base/index.html", 
        {'last_ones': last_ones,   'first_ones' : first_ones})  

Index.html shows the HTML content but not the content of the loop

#index.html

<div class="col-md-6">
    <p> Chosen Items negative:</p>
    {% for startup in last_ones %}
        <li><p>{{ startup.title }}</p></li>
    {% endfor %}
</div>

<div class="col-md-6">
    <p> Chosen Items positive:</p>
    {% for startup in first_ones %}
       <li><p>{{ startup.title }}</p></li>
    {% endfor %}

Here my problem:

How can I get the for loop to render the specific content?

I think Django show render_to_response in template comes very close to my problem, but i don't see a valid solution there.

Thank you for your help.

Chris

-- I edited my code and problem description based on the solutions provided in this thread

Community
  • 1
  • 1
  • 1
    the call `render_to_response("base/showlatest.html"...` renders `base/showlatest.html`, not `index.html`. The view responsible for rendering `index.html` should pass all data (`last_ones` and `first_ones`) to it – Pynchia Aug 03 '15 at 14:46

1 Answers1

1

the call render_to_response("base/showlatest.html"... renders base/showlatest.html, not index.html.

The view responsible for rendering index.html should pass all data (last_ones and first_ones) to it.

Once you have included the template into index.html

{% include /base/showlatest.html %}

Change the view above (or create a new one or modify the existing, changing urls.py accordingly) to pass the data to it

return render_to_response("index.html", 
{'last_ones': last_ones,   'first_ones' : first_ones})

The concept is that the view renders a certain template (index.html), which becomes the html page returned to the client browser. That one is the template that should receive a certain context (data), so that it can include other reusable pieces (e.g. showlatest.html) and render them correctly.

The include command just copies the content of the specified template (showlatest.html) within the present one (index.html), as if it were typed in and part of it.

So you need to call render_to_response and pass it your data (last_ones and first_ones) in every view that is responsible for rendering a template that includes showlatest.html

Sorry for the twisted wording, some things are easier done than explained. :)

UPDATE

Your last edit clarified you are using CBV's (Class Based Views).

Then your view should be something along the line:

class LandingView(TemplateView):
    template_name = "base/index.html"

    def get_context_data(self, **kwargs):
        context = super(LandingView, self).get_context_data(**kwargs)
        context['last_ones'] = coremodels.Startup.objects.all().order_by('-id')[:5]
        context['first_ones'] = coremodels.Startup.objects.all().order_by('id')[:5]
        return context

Note: personally I would avoid relying on the id set by the DB to order the records.

Instead, if you can alter the model, add a field to mark when it was created. For example

class Startup(models.Model):
    ...
    created_on = models.DateTimeField(auto_now_add=True, editable=False)

then in your view the query can become

    def get_context_data(self, **kwargs):
        context = super(LandingView, self).get_context_data(**kwargs)
        qs = coremodels.Startup.objects.all().order_by('created_on')
        context['first_ones'] = qs[:5]
        context['last_ones'] = qs[-5:]
        return context
Pynchia
  • 10,996
  • 5
  • 34
  • 43
  • First of all, thanks for your quick reply. I would upvote it, but i don't have enough reputation points to do this yet. I think i understood what you mean. I put the code of showlatest.html into index.html, i put the index_filtered function into my index view and changed the render from base.html to index.html (I updated everything in the OP). Unfortunately it still doesn't work. Is there anything i'm missing or understood wrong? – chrtothaizzo Aug 04 '15 at 10:45
  • there is no need to discard `showlatest.html`, the include was fine and it's the way to go if you are going to use it in another template. – Pynchia Aug 04 '15 at 13:48
  • ehm.. you omitted to explain you plan to use CBV (Class-Based-Views). If so, when do you think is `index_filtered` going to be called? You should override `get` or even better `get_context_data`. Use [this great website](http://ccbv.co.uk/projects/Django/1.8/django.views.generic.base/TemplateView/) for help on CBVs – Pynchia Aug 04 '15 at 13:58
  • 1
    Awesome, thank you very much. Works like a charm now! I guess there is still a lot of reading to do to understand CBV and other basics in Django ;) – chrtothaizzo Aug 04 '15 at 15:19