Django ListView not working on the template - django

I am trying for hours on a problem that seems very straightforward and I tried everything but it's not working. I want to display the list of blogs on a template. So, I have these views:
from django.views import generic
from .models import Blog
class BlogList(generic.ListView):
queryset = Blog.objects.filter()
template_name = 'table_of_contents.html'
context_object_name = 'blog_list'
class BlogDetail(generic.DetailView):
model = Blog
template_name = 'blog.html'
And this is the table_of_contents.html template where I want to display the list of blogs:
{% block table_of_contents %}
<p>Just for test</p>
{{ blog_list }}
{%endblock table_of_contents %}
I expect that would display the queryset string on the frontend, but that's not the case. I debugged BlogList using the Django shell and made sure that queryset was not empty.
What is the (obvious) detail that I am missing here?
Edit:
Here is the blog.html template as well:
{% extends 'base.html' %}
{% block content %}
<p>Test blog template</p>
{% block table_of_contents %} {% include 'table_of_contents.html' %} {% endblock table_of_contents %}
{% endblock content %}
Again, the querystring is not rendered at all, no matter if I use a for loop or just do {{ blog_list }}.

The queryset will look like <QuerySet …>, so that will not render effectively on the page, since it will assume that <QuerySet as a HTML tag, not as content.
What you can do is iterate over the items in the QuerySet, and render these individually, for example:
{% block table_of_contents %}
<p>Just for test</p>
{% for blog in blog_list %}
{{ blog.title }}
{% endfor %}
{%endblock table_of_contents %}
of course here I assume that your Blog model has a title field. You might need to change this to a different field.
If you define a {% block … %} [Django-doc] this means you need to inherit from a parent template that specifies a block with the name table_of_contents.
You thus need to have a parent template, for example:
<!-- parent.html -->
My page
{% block table_of_contents %}
{% endblock table_of_contents %}
in your template where you list the blogs, you thus then inherit from the parent.html page with the {% extends … %}:
{% extends 'path/to/parent.html' %}
{% block table_of_contents %}
<p>Just for test</p>
{% for <b>blog in blog_list</b> %}
{{ blog<b>.title</b> }}
{% endfor %}
{%endblock table_of_contents %}

Related

Django: how to pass value from a list template to a view, static url

In my template, I have a list of users on which the connected user can click to access the profile of a user on the list. I want to retrieve the user I clicked on in my view. However, I would like to keep a static URL (to avoid having user-related settings displayed in the URL). Do you have any idea how to do that?
Here is my template :
{% extends "base.html" %}
{% block content %}
{% if userConnected.adminRole == "SuperUser" %}
<h2>Members List</h2>
<h3>Members from OU : {{ userConnected.ou }} </h3>
{% for element in user_list %}
<p>{{ element.first_name }}</p>
{% endfor %}
{% endif %}
{% endblock %}
What should I add to my template and what should I write in my view "edit_other_profile" to get the right user ? Thanks a lot

Django inclusion_tag contents not displaying

I cannot get the contents of an inclusion_tag to display. I am not getting an errors so i know that the tag is registering and I am almost certain that it is loading correctly. The tag is created in crudapp/templatetags/crudapp_tags.py
from django import template
register = template.Library()
#register.inclusion_tag("forum.html")
def results(poll):
form = 'blah'
return {'form': form}
templates/forum.html
{% extends 'index.html' %}
{% load crudapp_tags %}
{% results poll %}
<p>aaa</p>
{% block homepage %}
<p>bbb</p> <!-- Only this displays -->
{% if form %}
<p>Form exists</p>
{% endif %}
{% for item in form %}
<p>This is {{ item }}</p>
{% endfor %}
<div>
<p>{% if user.is_authenticated %}Add a New Topic: <span class="glyphicon glyphicon-plus"></span>{% endif %}</p>
</div>
<div>
<p>{{ totalposts.count }} posts, {{ totaltopics.count }} topics, {{ totalusers.count }} users, {{ totalviews.numviews}} views</p>
</div>
{% endblock %}
The file set up is as follows,
If you are using an inclusion tag, then the tag renders another template. You need to move the code that uses form out of forum.html and into a new template, e.g. results.html
results.html
{% if form %}
<p>Form exists</p>
{% endif %}
{% for item in form %}
<p>This is {{ item }}</p>
{% endfor %}
Then change your tag to use this template
#register.inclusion_tag("results.html")
def results(poll):
form = 'blah'
return {'form': form}
Finally, since you are extending a template, you need to move then tag into a block, otherwise the result won't be used.
{% block homepage %}
{% results poll %}
...
{% endblock %}
If you want to add an item to the template context instead of rendering another template, then you want a simple tag instead.
#register.simple_tag
def fetch_result():
result = ['foo', 'bar']
return result
Then in your template:
{% fetch_result as result %}
{% for item in result %}
<p>This is {{ item }}</p>
{% endfor %}
The {% fetch_result as result %} works for simple tags in Django 1.9+. In earlier versions, you want an assignment tag.

Django: with tag outside blocks

It seems like the 'with' tag is not working if it is declared outside of a block as this:
{% extends 'base.html' %}
{% with my_var=1 %}
{% block test1 %}
{{my_var}}
{% endblock %}
{% block test2 %}
{{my_var}}
{% endblock %}
{% endwith %}
The template above simply displays nothing since my_var is NOT passed inside those blocks.
How can I overcome this?
I came to Django from using Tornado with Jinja2 and I was being driven insane by the inability to set variables that (a) could be defined in the template (not view) and (b) would be available in the base template that this derives from. Looking at a little four-line piece of code from django-libs, I was able to rig up something like this that worked well. Here is an example of a title string that should appear in various blocks.
settings.py -- add to TEMPLATES (Django 1.10+)
TEMPLATES = {
...
builtins = ['mysite...wherever...templatetags',]
}
mysite.whereever.templatetags.py
from django import template
register = template.Library()
#register.simple_tag(takes_context=True)
def setvar(context, key, value):
context.dicts[0][key] = value
return ''
base.html
{% block settings %}
{% comment %}
Put this at the TOP of the template before
any blocks that use variables.
{% endcomment %}
{% endblock settings %}
<html>
<head><title>{{title}}</title></head>
<body><h1>My Site: {{title}}</h1>
{% block body %}
{% endblock body %}
</body></html>
menu.html -- a template that does not set 'title' in views:
{% extends "base.html" %}
{% block settings %}
{{ block.super }} {% comment %}optional{% endcomment %}
{% setvar 'title' 'Menu' %}
{% endblock %}
{% block body %}
<ul><li>Fish</li><li>Steak</li></ul>
{% endblock %}
Now the title will appear in two places in the HTML even though it is defined in the derived template but appears in the top template.

Django mptt, extends "base.html"

In base.html:
<div id="menu_shop">
<input name="search" placeholder="search">
<p>Category:</p>
{% load mptt_tags %}
<ul class="root">
{% recursetree nodes %}
<li>
{{ node.name }}
{% if not node.is_leaf_node %}
<ul class="children">
{{ children }}
</ul>
{% endif %}
</li>
{% endrecursetree %}
</ul>
</div>
in views:
def show_category_tree(request):
return render_to_response("base.html",
{'nodes': Category.tree.all()},
context_instance=RequestContext(request))
urls.py:
url(r'^category/', 'item.views.show_category_tree'),
url(r'^category/(?P<slug>[\w\-_]+)/$', 'item.views.by_category'),
How to display this in "by_category.html"
If I try(for example):
{% extends "base.html" %}
{% block content %}
{% for e in entries %}
<p><b>{{ e.name}}</b></p>
<p>{{ e.desc}}</p>
{% endfor %}
{% endblock %}
I have this error:
http://dpaste.com/810809/
{% extends "base.html" %} does not work. If I remove it, everything works.
You are seeing this error because your template context for the by_category does not include nodes.
The extends tag is related to the template, not the view. It makes your by_category.html template extend the base.html template, but it does not include the template context from any other view.
The easiest fix would be to add nodes to your template context in the by_category view.
def by_category(request, slug):
entries = Entry.objects.filter(...)
return render_to_response("base.html",
{'entries': entries,
'nodes': Category.tree.all()},
context_instance=RequestContext(request))
This would be repetitive if you want to display the nodes in lots of other views. If you want to include the nodes in all views, you may want to write a request context processor. If you want to include it in some but not all pages, then try writing a custom template tag.

How to redirect back to same page when errors in Django comments

How do you get Django comments to redirect back to the same page where you're filling out a comment if there are errors in the comment submission form?
So basically I have a template like this:
{% block content %}
{% render_comment_form for show %}
{% get_comment_count for show as comment_count %}
<div id="comments-count">
{% if comment_count == 0 %}
No comments yet. Be the first!
{% else %}
Number Of Comments: {{ comment_count }}
{% endif %}
</div>
{% if comment_count > 0 %}
{% render_comment_list for show %}
{% endif %}
{% endblock %}
I created my own list.html and form.html and everything looks fine. In the form.html template there is some code like this:
<ul class="form-errors">
{% for field in form %}
{% for error in field.errors %}
<li>{{ field.label }}: {{ error|escape }}</li>
{% endfor %}
{% endfor %}
</ul>
So obviously, if there is an error in the comment submission form, I would like the user to see the same page as before only with some errors displayed in the comments form. Or alternatively if this is not possible, just ignore the error and instead of transitioning to the preview.html template, it would just not save the comment and again go back to the page.
Any help? Note ideally I dont want to have to create a custom comments app. This functionality should be there already. I know there's a next variable you can pass (and I am doing this), but it only works if the comment form is successful.
you have to use HttpResponseRedirect
from django.http import HttpResponseRedirect
def comment_form(request):
error = request.GET.get('error', None)
requestDict = {'error': error}
return render_to_response('comments.html', requestDict, context_instance=RequestContext(request))
def post_comment(request):
....
your code
....
if something_goes_wrong:
HttpResponseRedirect('project/comment_form/?error=ThereisProblem')
And in template you can do this:
{If error %}
<h1>{{error}}<h1>
{%else%}
render comments...
{%endif%}
Hope this will help you :)