I was on the 3rd tutorial of this https://docs.djangoproject.com/en/1.5/intro/tutorial03/ site. I got stuck where we load template for our views under the section Write views that actually do something.
The first code is working fine ( as there is no template loading):
from django.http import HttpResponse
from polls.models import Poll
def index(request):
latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
output = ', '.join([p.question for p in latest_poll_list])
return HttpResponse(output)
But when I laod the template with code below it shows same result as above( that is
with no template)
from django.http import HttpResponse
from django.template import Context, loader
from polls.models import Poll
def index(request):
latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
template = loader.get_template('polls/index.html')
context = Context({
'latest_poll_list': latest_poll_list,
})
return HttpResponse(template.render(context))
The template use is:
{% 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 %}
The template is in polls/template/polls/index.html where polls is my app( as used in tutorial)
PS:I have followed everything as it is till this point from tutorial.
As you can see in the Django documentation, django.template.loaders.app_directories.Loader looks for template files in a directory named templates inside the app directory.
You said that your template is in "polls/template/polls/index.html", but it should be in "polls/templates/polls/index.html" (notice the added s to templates).
Related
Sorry for the dumb question, I'm lost.
I got a template and a templatetags with this :
menu_tags.py
from django import template
from menu.models import Button
register = template.Library()
#register.inclusion_tag('menu/home.html')
def show_menu():
buttons = Button.objects.all()
return {'buttons': buttons}
And this :
home.html
{% for button in buttons %}
{% if user.is_authenticated %}
stuff
{% endif %}
{% endfor %}
I would like to know, how can I make user.is_authenticated work ? I know I have to import something, but where ? Importing it in menu_tags does not seems to work.
Thanks !
As suggested by other users in the comments, try the following:
from django import template
from menu.models import Button
register = template.Library()
#register.inclusion_tag('menu/home.html', takes_context=True)
def show_menu():
request = context['request']
if request.user.is_authenticated: # if Django 1.10+
buttons = Button.objects.all()
else:
buttons = None
return {'buttons': buttons}
And then in your template, make sure you load your new templatetags and try:
{% load menu_tags %}
{% for button in buttons %}
{{ button }}
{% endfor %}
I was following the django documentation and making a simple poll app. I have come across the following error :
Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
^polls/
^admin/
The current URL, , didn't match any of these."
settings.py
ROOT_URLCONF = 'mysite.urls'
mysite/mysite/urls.py
from django.conf.urls import include,url
from django.contrib import admin
urlpatterns = [
url(r'^polls/',include('polls.urls')),
url(r'^admin/', admin.site.urls),]
mysite/polls/urls.py
from django.conf.urls import url
from . import views
app_name= 'polls'
urlpatterns=[
url(r'^$',views.IndexView.as_view(),name='index'),
url(r'^(?P<pk>[0-9]+)/$',views.DetailView.as_view(), name='detail'),
url(r'^(?P<pk>[0-9]+)/results/$',views.ResultsView.as_view(),name='results'),
url(r'^(?P<question_id>[0-9]+)/vote/$',views.vote,name='vote'),]
mysite/polls/views.py
from django.shortcuts import get_object_or_404,render
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.views import generic
from django.utils import timezone
from django.template import loader
from .models import Choice,Question
from django.template.loader import get_template
#def index(request):
# return HttpResponse("Hello, world. You're at the polls index")
class IndexView(generic.ListView):
template_name='polls/index.html'
context_object_name='latest_question_list'
def get_queryset(self):
"""Return the last five published questions."""
return Question.objects.filter(pub_date__lte=timezone.now()).order_by('-pub_date')[5:]
class DetailView(generic.DetailView):
model=Question
template_name='polls/detail.html'
def get_queryset(self):
"""
Excludes any questions that aren't published yet.
"""
return Question.objects.filter(pub_date__lte=timezone.now())
class ResultsView(generic.DetailView):
model= Question
template_name ='polls/results.html'
def vote(request, question_id):
question=get_object_or_404(Question, pk=question_id)
try:
selected_choice= question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
return render(request, 'polls/details.html',
{
'question':question,
'error_message' : "You didn't select a choice" ,
})
else:
selected_choice.votes+=1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
index.html
<!DOCTYPE HTML >
{% load staticfiles %}
<html>
<body>
<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}" />
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="{% url 'polls:detail' question.id %}">{{question.question_test }}
</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
</body>
</html>
This link http://127.0.0.1:8000/polls/ shows a blank page with 3 bullets. (I have 3 questions in my database and their id's are 5,6,7 because I have been deleting and adding the questions.)
My admin works fine!
I'm new to Django and have been searching and asking around and have been stuck on it for a while now.
You get the 404 on http://127.0.0.1:8000/ because you have not created any URL patterns for that url. You have included the url http://127.0.0.1:8000/polls/, because you have included the polls urls with
url(r'^polls/',include('polls.urls')),
The empty bullets suggest that there is a problem with your polls/index.html template. It looks like you have a typo and have put {{ question.question_test }} instead of {{ question.question_text }}. Make sure that it exactly matches the template from the tutorial 3:
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li>{{ question.question_text }}</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
Make sure there is no typo in your code. Putting space between inverted commas can also lead to this error. Just make sure you have put path('',include('home.urls')) and not path(' ',include('home.urls'))
Note: here home.urls is the name of my app in Django
Assuming my model contains data, I have myapp/views.py:
from django.template import RequestContext
from django.shortcuts import render
from .models import History
import datetime
def live_view(request):
context = RequestContext(request)
plays_list = History.objects.filter(date=datetime.date(2016,04,22))
context_list = {'plays':plays_list}
return render(request,'live.html',context_list)
myapp/templates/live.html:
{% extends 'base.html' %}
{% block content %}
{% for key, value in context_list.items %}
{{ value }}
{% endfor %}
{% endblock %}
myapp/urls.py:
from myapp.views import live_view
urlpatterns = [url(r'^live/$', live_view, name="live"),]
The output is a page that renders only the base.html template, with no content in the body. What's wrong with my view function or template rendering? Should I be inheriting from TemplateView?
You don't pass anything called context_list to the template. What you pass is the contents of that dict, which in this case is just plays.
I am trying to nest tornado templates using {% include %}:
<html>
{% for headline in HL['headlines'] %}
{% include 'hl_1.html' %}
{% end %}
</ul>
</body>
</html>
The template above works, and the sub-template above works. What I cannot figure out how to do is pass in the name of the sub-template (e.g.replacing 'hl_1.html' with a string parameter in the parent template's namespace). AFter reviewing the template.py source code it seems that {% include accepts a string and nothing else. But it would be fantastic if one could dynamically specify sub-templates.
Has anyone tried this and succeeded?
thanks
The way this is achieved usually is by using UI modules.
This is how I would structure your app.
First main.py:
import tornado.ioloop
import tornado.web
import views
class MainHandler(tornado.web.RequestHandler):
def get(self):
HL = {
'headlines': ['head1', 'head2', 'head3'],
}
self.render('tmpl.html', HL=HL)
if __name__ == "__main__":
application = tornado.web.Application([
(r"/", MainHandler),
], ui_modules=views)
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
Then your template tmpl.html:
<html>
{% for headline in HL['headlines'] %}
{% module Headline(headline) %}
{% end %}
</ul>
</body>
</html>
Finally, views.py, where you can define all your UI modules:
from tornado.web import UIModule
class Headline(UIModule):
def render(self, name):
return '<h1>%s</h1>' % name
UI modules are like "reusable templates", that accept parameters.
im doing something with feedparser: i have a templatetag for display "news" in my home page, but , how ill limit the feedparser result?
inclusion tag
from django.template import Template, Library
import feedparser
register = Library()
#register.inclusion_tag('rss_render.html')
def rss_render(object): #RSS URL "object"
rss = feedparser.parse(object)
return {'rss': rss}
template
<ul>
{% for r in rss.entries %}
<li> {{ r.title }}</li>
{% endfor %}
</ul>
Take this Django snippet for example.
You can use Django's slice template tag:
{% for r in rss.entries|slice:":10" %}
http://docs.djangoproject.com/en/dev/ref/templates/builtins/#slice