Django isn't finding my objects - django

I'm running through the django tutorial, and built the sample polls app. I've got 5 polls in the system, visible through the admin interface to me. However, my rudimentary index view and template don't seem to display them(instead, the template defaults to the else clause as if there were no polls).
My index view is as follows:
def index(request):
latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
return render_to_response('index.html', {'latest_poll_list': latest_poll_list})
And the template index.html:
{% if latest_poll_List %}
<ul>
{% for poll in latest_poll_list %}
<li>{{ poll.question }}</li>
{% endfor %}
</ul>
{% else %}
<p> No polls are available.</p>
{% endif %}
I can even do polls = Poll.objects.all() (with or without order_by and the truncation) in the manage.py shell, and it returns everything fine. What gives?

It could be a simple typo: latest_poll_List should be latest_poll_list with a lower case L on the list. Otherwise maybe try:
{% if latest_poll_list.count > 0 %}
...
{% endif %}
Also try:
{{ latest_poll_list }}
in your template somewhere to see if it prints out the correct list of objects (i.e. the template is getting the correct list of polls)

Related

Django template variable not set

The title says everything. Two days ago the following code worked fine but now journeys is not set or empty or ...
def map(request, jid):
journeys = None
if request.user.is_authenticated:
journeys = Journey.objects.filter(user_id=request.user.id)
#some stuff
context = {
'jc': len(journeys), #only for testing
'journeys': journeys
}
return render(request, 'JourneyMap/map.html', context)
map.html extends base.html
Inside base.html:
<div class="dropdown-menu" aria-labelledby="dropdown05">
<p>{{ jc }}</p> <-- only for testing
{% for journey in journeys %}
{% if journey.user_id == user.user_id %}
{% if forloop.counter < 4 %}
<a class="dropdown-item"
href="{% url 'JourneyMap_journey' jid=journey.id %}">{{ journey.title }}</a>
{% endif %}
{% endif %}
{% endfor %}
</div>
Result:
It seems like journeys length is 1, so the variable is actually set.
I think that your user check fails here.
{% if journey.user_id == user.user_id %}
What is user.user_id here? Is user another variable that lives somewhere outside of the given context? Then probably it's not set.
Otherwise, if you want to check for current user's id, perhaps you should do:
{% if journey.user_id == request.user.id %}

Get a random object of a Wagtail page model but not the current one

So I have this template context processor:
from cases.models import CasePage
def random_case(request):
case = CasePage.objects.live().order_by('?')
return {'random_case': case}
And in the template I do this:
{% for entry in random_case %}
{% if request.get_full_path != entry.get_url %}
{% if forloop.first %}
<a class="ajax-link project-next" href="{{ entry.get_url }}">
<div class="nav-project-title">{{ entry.title }}</div>
<div class="nav-title">next</div>
</a>
{% endif %}
{% endif %}
{% endfor %}
And this works but the problem is sometimes the object is the same as the page so nothing is displayed. It would be great if that one would be skipped in favour of the next entry. And it's also too much logic in the template for me. What would be the best way to move this logic into the context processor and make it work?
Make random_case a method of CasePage, and filter out the case with an ID equal to self.
class CasePage(Page):
# ...
def random_case(self):
return CasePage.objects.live().exclude(id=self.id).order_by('?').first()
You can then refer to this method within your template as page.random_case - bear in mind that a new random choice will be made on each call, so you probably want something like {% with page.random_case as case %}.

How to change template based on user authentication in django

If user successfully login i need to show one template. if user not login i need to show another template.
I created two templates one is base.html another one is base_login.html template.
IF user successfully login i need to call base_login.html other wise base.html. i am using below to achieve this. it's not giving expected result. How do achieve this?
{% if user.is_authenticated %}
<p>Welcome {{ user.username }} !!!</p>
{% extends "base_login.html" %}
{% else %}
{% extends "base.html" %}
{% endif %}
If your template goes invalid, I suggest you to it at the views.py, an example:
from django.shortcuts import render, render_to_response
def homepage(request):
template_name = 'homepage.html'
extended_template = 'base_login.html'
if request.user.is_authenticated():
extended_template = 'base.html'
return render(
request, template_name,
{'extended_template': extended_template, ...}
)
# homepage.html
{% extends extended_template %}
{% block content %}
{% if request.user.is_authenticated %}
Hello {{ request.user }}
{% endif %}
{% endif %}
Note: if function of render still doesn't work well, please try with render_to_response such as this answer: https://stackoverflow.com/a/1331183/6396981

Custom Template Tag Queryset Not Returning Anything

I'm trying to implement a feature that displays the 5 most recently created events. I decided to implement this with Django custom template tags (if this is not the best way, let me know). What I have so far is:
In event_search.html (among other things):
{% extends 'base.html' %}
{% load eventSearch_extras %}
<p>count: {{ recents.count }}</p>
<ul>
{% for e in recents %}
<li> {{e.title}} </li>
{% empty %}
<li> No recent events </li>
{% endfor %}
</ul>
In eventSearch_extra.py:
from django import template
from eventSearch.models import Event
register = template.Library()
#register.inclusion_tag('eventSearch/event_search.html')
def mostrecentevents():
"""Returns most 5 most recent events"""
recents = Event.objects.order_by('-created_time')[:5]
return {'recents': recents}
My issue here is that the queryset 'recents' appears to return empty to the template. 'count:' shows nothing & the for-loop defaults to 'No recent events'.
You've loaded the inclusion tag function, but not the individual tag, so the code to populate that information is never called; it's also laid out slightly oddly, so you're calling from the wrong place.
The main template calls the inclusion tag by using:
{% load eventSearch_extras %}
And you include the actual tag by calling
{{mostrecentevents}}
mostrecentevents goes off and runs the code, parses the html of event_search.html and puts it in the main template. The way your code is set out just now, you'd be calling an inclusion tag from its own HTML.
Main template > {% load inclusion_tags %} {{ actual_tag }}
As an example, I have a restaurant template. In that template is this code:
{% load restaurant_menu %} <!--main inclusion tag .py file) -->
{% menu %} <!-- the actual tag code you want to run -->
in restaurant_menu.py I have the following (additional irrelevant stuff removed):
#register.inclusion_tag('core/_menu.html', takes_context=True)
def menu(context):
filtered = context['filtered']
from core.models import MenuItem, FoodProfile, Ingredient, Recipe
if filtered:
restaurant = context['restaurant'].id
filtered_menu = #stuff here
restaurant_menu = filtered_menu
else:
restaurant_menu = MenuItem.objects.filter(restaurant__pk=context['restaurant'].id)
return {"restaurant_menu": restaurant_menu,
"number_of_menu_items": restaurant_menu.count(),
"filtered": filtered}
and the _menu.html page (underscored so I know it's a fragment) :
<ul>
{% for item in course.list %}
<li>
{{ item.number|floatformat:0 }} {{ item.name }} {{ item.description }} {{ item.price }} </li>
</li>{% endfor %}
{% endfor %}
</ul>
An inclusion tag is used to render another template. It doesn't make sense to create an inclusion tag that renders event_search.html, then call that template tag inside event_search.html itself. Note that you haven't actually used the template tag (with {% mostrecentevents %}), all you have done is load the template tag library.
It would be easier to use a simple tag instead.
#register.simple_tag
def mostrecentevents():
"""Returns most 5 most recent events"""
recents = Event.objects.order_by('-created_time')[:5]
return recents
Then in your template you can do:
{% load eventSearch_extras %}
{% mostrecentevents as recents %}
This loads the result of the template tag into the variable recents, and you can now do:
<p>count: {{ recents.count }}</p>
<ul>
{% for e in recents %}
<li> {{e.title}} </li>
{% empty %}
<li> No recent events </li>
{% endfor %}
</ul>
Note you can only use the as recents syntax with simple tags with Django 1.9+. For earlier versions, you can use an assignment tag instead.

Django nested QuerySet yielding nothing

I am using Django 1.8 with Postgres 9.2 on a Windows 8 machine.
I have two pieces of nearly identical code from two of my projects. One works and the other doesn't.
Here's the code that works:
# views.py
from django.shortcuts import render
from models import Artist, Track
def music(request):
artists = Artist.objects.all().order_by('orderName')
artistTrackCollections = []
for artist in artists:
artist.tracks = Track.objects.filter(artist=artist).order_by('order')
artistTrackCollections.append(artist)
return render(request, 'music.html', {'artistTrackCollections': artistTrackCollections,})
And the relevant template code:
{% for artist in artistTrackCollections %}
<dl>
<dt>
{% if artist.website %}
<h2>{{ artist.name }}</h2>
{% else %}
<h2>{{ artist.name }}</h2>
{% endif %}
</dt>
<dd>
<ul>
{% for track in artist.tracks %}
<li>“{{ track.title }}”
<i>({{ track.album.title }})</i>
{% endfor %}
</ul>
</dd>
</dl>
{% endfor %}
Now here's pretty much the exact same code from a different project of mine that doesn't work anymore:
def index(request):
productList = PartModel.objects.filter(isBuild=True, isActive=True).order_by('name')
productCollection = []
for product in productList:
product.part_list = product.buildpart.all().order_by('family__type')[:5]
productCollection.append(product)
return render(request, 'index.html', { 'productCollection': productCollection, })
and its corresponding template:
{% for product in productCollection %}
<p>{{ product.name }}
<p>${{ product.price }}
<ul>
{% for part in product.part_list %}
<li>{{ part.family.type.name }} | {{ part.name }}
{% endfor %}
</ul>
{% endfor %}
This code used to work but now it doesn't. In the code that works I succeed in going through each artist and attaching that artist's tracks. In the code that fails I try to go through each PartModel instance that is a build and get that PartModel instance's corresponding parts. They are identical as far as I can tell. productCollection gets populated but the part_list data for some reason is blank. This leads me to believe the problem is with this line:
product.part_list = product.buildpart.all().order_by('family__type')[:5]
But I cannot discern the difference from this line:
artist.tracks = Track.objects.filter(artist=artist).order_by('order')
Thanks in advance for any help!