I am new to django. I am not able to render a template using two or multi level dictionary.Below are my view and template code.
code from view.py
myList = {
'ParentABC': {
'ABC' : '#'
}
}
return render_to_response('index.html', myList)
I have tried with two different templates but no luck:
Template1-
<ul class="collapsible collapsible-accordion">
{% for eachCategory in myList %}
<li class="bold"><a class="collapsible-header waves-effect waves-teal">{{ eachCategory }}</a>
<div class="collapsible-body" style="">
<ul>
{% for subCat in myList.eachCategory %}
<li>{{ subCat }}</li>
{% endfor %}
</ul>
</div>
</li>
{% endfor %}
</ul>
template 2-
<ul class="collapsible collapsible-accordion">
{% for category,value in myList.items %}
<li class="bold"><a class="collapsible-header waves-effect waves-teal">{{ category }}</a>
<div class="collapsible-body" style="">
<ul>
{% for subcategory,value1 in value.items %}
<li>{{ subcategory }}</li>
{% endfor %}
</ul>
</div>
</li>
{% endfor %}
</ul>
after rendering i am always getting below html:
<ul class="collapsible collapsible-accordion">
</ul>
Please help me for the same.
Use following code sample
myList = {
'myList' : {
'ParentABC1': {
'ABC' : '#',
'DEF' : '#'
},
'ParentABC2': {
'ABC' : '#',
'DEF' : '#'
},
}
}
<ul class="collapsible collapsible-accordion">
{% for eachCategory, value in myList.items %}
<li class="bold"><a class="collapsible-header waves-effect waves-teal">{{ eachCategory }}</a>
<div class="collapsible-body" style="">
<ul>
{% for subCat in value %}
<li>{{ subCat }}</li>
{% endfor %}
</ul>
</div>
</li>
{% endfor %}
</ul>
Use {% for key, value in object.iteritems %} if you want to iterate on an object with keys and values, or just {% for value in object.items %}
Something like
<ul class="collapsible collapsible-accordion">
{% for eachCategory, catValue in myList.iteritems %}
<li class="bold"><a class="collapsible-header waves-effect waves-teal">{{ eachCategory }}</a>
<div class="collapsible-body" style="">
<ul>
{% for subCat in catValue.items %}
<li>{{ subCat }}</li>
{% endfor %}
</ul>
</div>
</li>
{% endfor %}
</ul>
Related
So I'm trying to use pagination, When I visit the page I get TypeError at /products/
object of type 'ModelBase' has no len(). The traceback shows this line has the error
books = haha.page(page)
views.py
def showproducts(request):
oof = CartItem.objects.filter(user=request.user).values_list('book', flat=True)
lmao = OrderItem.objects.filter(user=request.user).values_list('book', flat=True)
hehe = CartItem.objects.filter(user=request.user)
category = Category.objects.all()
haha = Paginator(Book, 2)
page = request.GET.get('page')
if page is None:
page = 1
fianlprice = 0
for item in hehe:
fianlprice += item.book.price
# books = Book.objects.all()
books = haha.page(page)
return render(request, 'main/products.html', {'books':books, 'price':fianlprice, 'cart':oof, 'order':lmao, 'category':category})
products.html
<h1>Products</h1>
<h1>{{ error }}</h1>
{% if user.is_authenticated %}
<h1>Your cart currently costs ${{ price }}</h1>
{% else %}
<h1>Please login to view your cart</h1>
{% endif %}
<form method="GET" action="/search/">
<label>Choose a category</label>
<select name="category" id="category">
<option value="All" selected>All</option>
{% for name in category %}
<option value="{{ name.name }}">{{ name.name }}</option>
{% endfor %}
</select>
<input type="text" placeholder="Search here" name="search" id="search">
<button type="submit">Search</button>
</form>
{% for book in books %}
<h3>{{ book.name }}</h3>
<img src= "/media/{{ book.image }}" alt="">
<p>{{ book.description }}</p>
{% if not user.is_authenticated %}
<p>Please login</p>
{% else %}
{% if book.id in cart %}
<form method="POST" action="/removefromcartforhome/">
{% csrf_token %}
<button type="submit" name="removeid" value="{{ book.id }}">remove item from cart</button>
</form>
{% elif book.id in order %}
<h3>You already own this</h3>
{% else %}
<form method="POST" action="/addtocartforhome/">
{% csrf_token %}
<button type="submit" name="bookid" value="{{ book.id }}">Add to cart</button>
</form>
{% endif %}
{% endif %}
{% endfor %}
{% if books.has_other_pages %}
{% if listing.has_previous %}
<li class="page-item">
«
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link">«</a>
</li>
{% endif %}
{% for i in books.paginator.page_range %}
{% if books.number == i %}
<li class="page-item active">
<a class="page-link">{{i}}</a>
</li>
{% else %}
<li class="page-item">
{{i}}
</li>
{% endif %}
{% endfor %}
{% if books.has_next %}
<li class="page-item">
»
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link">»</a>
</li>
{% endif %}
{% else %}
{% endif %}
The paginator needs a QuerySet, not a model, so:
# queryset ↓
haha = Paginator(Book.objects.all(), 2)
I have a template which includes 4 different paginators that only differ in context variables (tasks_today, tasks_tomorrow, ... etc.), and I want to minimise code repetition so I don't have 4 different paginator templates.
Template:
<div class="wrapper">
<h3>Today</h3>
<table>
{% if tasks_today %}
{% for task in tasks_today %}
{% include 'todo/task_table_row.html' %}
{% endfor %}
{% include 'todo/paginator_today.html' %}
{% else %}
<p>No tasks for today.</p>
{% endif %}
</table>
<h3>Tomorrow</h3>
<table>
{% if tasks_tomorrow %}
{% for task in tasks_tomorrow %}
{% include 'todo/task_table_row.html' %}
{% endfor %}
{% include 'todo/paginator_tomorrow.html' %}
{% else %}
<p>No tasks for tomorrow.</p>
{% endif %}
</table>
<h3>Upcoming</h3>
<table>
{% if tasks_upcoming %}
{% for task in tasks_upcoming %}
{% include 'todo/task_table_row.html' %}
{% endfor %}
{% include 'todo/paginator_upcoming.html' %}
{% else %}
<p>No upcoming tasks.</p>
{% endif %}
</table>
<h3>Past</h3>
<table>
{% if tasks_past %}
{% for task in tasks_past %}
{% include 'todo/task_table_row.html' %}
{% endfor %}
{% include 'todo/paginator_past.html' %}
{% else %}
<p>No tasks in the past.</p>
{% endif %}
</table>
</div>
paginator_today:
{% load url_replace %}
{% if tasks_today %}
<div class='paginator'>
<nav aria-label="Page navigation">
<ul class="pagination">
{% if tasks_today.has_previous %}
<li class="page-item">
<a class="page-link" href="?{% url_replace page_today=1 %}" aria-label="Previous">
<span aria-hidden="true">«</span>
<span class="sr-only">begin</span>
</a>
</li>
{% endif %}
{% for n in tasks_today.paginator.page_range %}
{% if tasks_today.number == n %}
<li class="page-item active">
<span class="page-link">{{ n }}
<span class="sr-only">(current)</span>
</span>
</li>
{% elif n > tasks_today.number|add:'-3' and n < tasks_today.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?{% url_replace page_today=n %}">{{ n }}</a>
</li>
{% endif %}
{% endfor %}
{% if tasks_today.has_next %}
<li class="page-item">
<a class="page-link" href="?{% url_replace page_today=tasks_today.paginator.num_pages %}" aria-label="Next">
<span aria-hidden="true">»</span>
<span class="sr-only">end</span>
</a>
</li>
{% endif %}
</ul>
</nav>
</div>
{% endif %}
paginator_tomorrow:
{% load url_replace %}
{% if tasks_tomorrow %}
<div class='paginator'>
<nav aria-label="Page navigation">
<ul class="pagination">
{% if tasks_tomorrow.has_previous %}
<li class="page-item">
<a class="page-link" href="?{% url_replace page_tomorrow=1 %}" aria-label="Previous">
<span aria-hidden="true">«</span>
<span class="sr-only">begin</span>
</a>
</li>
{% endif %}
{% for n in tasks_tomorrow.paginator.page_range %}
{% if tasks_tomorrow.number == n %}
<li class="page-item active">
<span class="page-link">{{ n }}
<span class="sr-only">(current)</span>
</span>
</li>
{% elif n > tasks_tomorrow.number|add:'-3' and n < tasks_tomorrow.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?{% url_replace page_tomorrow=n %}">{{ n }}</a>
</li>
{% endif %}
{% endfor %}
{% if tasks_tomorrow.has_next %}
<li class="page-item">
<a class="page-link" href="?{% url_replace page_tomorrow=tasks_tomorrow.paginator.num_pages %}" aria-label="Next">
<span aria-hidden="true">»</span>
<span class="sr-only">end</span>
</a>
</li>
{% endif %}
</ul>
</nav>
</div>
{% endif %}
What can I do?
url_replace.py:
from django.utils.http import urlencode
from django import template
register = template.Library()
#register.simple_tag(takes_context=True)
def url_replace(context, **kwargs):
query = context['request'].GET.dict()
query.update(kwargs)
return urlencode(query)
You can use the with keyword to set certain variables inside your include template:
{% include 'todo/paginator.html' with tasks=tasks_today page='page_today' %}
You can then replace references to tasks_today in you paginator template to tasks, as well as the reference to page_today to page
Edit: The call to url_replace is problematic, since it uses kwargs, and a call like {% url_replace page_today = x %}, will be equivalent to a call to urlreplace(context, **{'page_today' : x}).
Simply calling url_replace with page = x will not work correctly, since it will pass a keyword argument with the name of page instead of the value of page
The naive solution would be to pass a page variable to the paginator.html and call {% urlreplace **{page : 20} %}, but the Django template engine does not allow packing kwargs.
I think the best way to go here is to create a url_replace_single function, since in this use case you only replaces one value.
To do this, you'll need to define a field and value parameter on you url_replace function:
#register.simple_tag(takes_context=True)
def url_replace(context, field, value, **kwargs):
query = context['request'].GET.dict()
query_dict = { field : value}
query.update(query_dict)
return urlencode(query)
Then call the function from your template like this:
{% url_replace field=page value=x %}
The only downside is that this will only let you replace one query parameter in your url.
Hi have the following piece of code that triggers an alert on Veracode:
#app.route('/user/<username>', methods=['GET'])
#login_required
def user(username):
username = str(escape(username))
if current_user.username == username:
user = User.query.filter_by(username=username).first_or_404()
all_regions = Region.query.all()
return render_template('user_bs.html', user=user, all_regions=all_regions,
production_mode=app.config['PRODUCTION_MODE'],
manual_registration=app.config['AUTHENTICATION_METHODS']['MANUAL'])
return redirect(url_for('index'))
I'm trying to understand what I can do to neutralize it.
In the user_bs.html template I'm properly surrounding my variables with curly brackets, double quotes etc...
What else can i do to prevent XSS?
This is the template:
{% extends "base.html" %}
{% block app_content %}
<div>
<table class="table">
<h3>My Profile</h3>
<tr >
<td>
<h1><img src="{{ user.avatar(32) }}"> {{ user.fullname }} </h1>
<p>Info: {{ user.description }}</p>
<p>Username: {{ user.username }}</p>
<p>Role: {% for role in user.roles %} {{ role }} {% endfor %}</p>
<p>Email: {{ user.email }}</p>
<p>Creation date: {{ user.creation_dt }}</p>
{% if user.last_seen %}<p>Last seen on: {{ user.last_seen }}</p>{% endif %}
</td>
</tr>
</table>
</div>
{% endblock %}
And base.html:
{% extends 'bootstrap/base.html' %}
{% block title %}
{% if title %}{{ title }}
{% elif frontend %} {{ frontend.name }} - test
{% else %} test
{% endif %}
{% endblock %}
{% block head %}
<meta charset="UTF-8">
{{super()}}
<link rel="icon" type="image/png" href="{{url_for('static', filename='images/favicon.ico')}}">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css">
{% endblock %}
{% block navbar %}
<div id="main">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{{ url_for('index') }}"><img src="{{url_for('static', filename='images/logo_navbar.png')}}" width="90px" alt="test" /></a>
{% if frontend %}
{% if frontend.analytics %}
<button id='toggle_analytics' class="btn btn-default navbar-btn active"><span class="glyphicon glyphicon-signal"></span>  Dashboard</button>
<button id='toggle_filters' class="btn btn-default navbar-btn"><span class="glyphicon glyphicon-tasks"></span>  Reports</button>
{% else %}
<button id='toggle_filters' class="btn btn-default navbar-btn active"><span class="glyphicon glyphicon-tasks"></span>  Reports</button>
{% endif %}
{% endif %}
</div>
<ul class="nav navbar-nav">
{% if frontends|length > 0 %}
{% for region in regions|sort(attribute='name') %}
{% set prod_lst = [] %}
{% for frontend in frontends %}
{% if frontend.region == region and frontend.activate %}
{% set prod_lst = prod_lst.append(frontend.product) %}
{% endif %}
{% endfor %}
<li class="dropdown">
{{ region.name }} <span class="caret"></span>
<ul class="dropdown-menu">
{% for product in products|sort(attribute='name') %}
{% if product in prod_lst %}
<h6 class="dropdown-header">{{ product.name }}</h6>
{% for frontend in frontends|sort(attribute='name') %}
{% if frontend.region == region and frontend.product == product %}
{% if frontend.activate %}
<li>{{ frontend.name }}</li>
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
</ul>
</li>
{% endfor %}
{% endif %}
</ul>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
{% if frontend %}
<p class="navbar-text align-right animated fadeInLeftBig animation-duration-500ms delay-3s" align="right"> {{ frontend.name }} :: <span class="glyphicon glyphicon-time"></span> {{ frontend.timezone.name }} :: <span id="clock"></span> </p>
{% else %}
<p class="navbar-text align-right animated fadeIn animation-duration-500ms" align="right"><span id="clock"></span> </p>
{% endif %}
{% if current_user.is_anonymous %}
<li>Login</li>
{% else %}
<li><span class="glyphicon glyphicon-home"></span></li>
<li><span><img src="{{ current_user.avatar(20) }}"></span></li>
{% if current_user.roles[0].name == 'Admin' %}
<li> <span class="glyphicon glyphicon-cog"></span> </li>
{% endif %}
<li> <span class="glyphicon glyphicon-log-out"></span></li>
{% endif %}
</ul>
</div>
</div>
</nav>
{% endblock %}
{% block content %}
<div class="container-fluid animated fadeIn animation-duration-100ms">
{% block app_content %}
{% endblock %}
</div>
</div>
{{super()}}
{%- block footer %}
<footer class="text-center">© 2019 test</footer>
{%- endblock footer %}
{% endblock content%}
{% block scripts %}
{{super()}}
<script src="{{url_for('static', filename='js/animate/custom.js')}}"></script>
{% endblock %}
I fixed it by simply changing the route:
#app.route('/user', methods=['GET'])
#login_required
def user():
user = User.query.filter_by(username=current_user.username).first_or_404()
all_regions = Region.query.all()
return render_template('user_bs.html', user=user, all_regions=all_regions,
production_mode=app.config['PRODUCTION_MODE'],
manual_registration=app.config['AUTHENTICATION_METHODS']['MANUAL'])
I have developed a django application. I added a paginator block to a webpage. It is placed on the wrong position. Instead, i want it to be placed below the list which is being shown. Actually, I am displaying group list on the page. Per page, only 5 group names will be displayed. Using pagination, i did that. But the problem is i am unable to place it in a correct position. I am attaching an image of the page.
The html page for this is:
{% extends "groups/group_base.html" %}
{% block pregroup %}
<div class="col-md-4">
<div class="content">
{% if user.is_authenticated %}
<h2>
Welcome back
#{{user.username }}
</h2>
{% endif %}
<h2>Groups</h2>
<p>Welcome to the Groups Page! Select a Group with a shared interest!</p>
</div>
{% if user.is_authenticated %}
<span class="glyphicon glyphicon-plus-sign"></span> Create New Group!
{% endif %}
</div>
{% endblock %}
{% block group_content %}
<div class="col-md-8">
<div class="list-group">
{% for group in object_list %}
<a class="list-group-item" href="{% url 'groups:single' slug=group.slug %}">
<h3 class="title list-group-item-heading">{{ group.name }}</h3>
<div class="list-group-item-text container-fluid">
{{ group.description_html|safe }}
<div class="row">
<div class="col-md-4">
<span class="badge">{{ group.members.count }}</span> member{{ group.members.count|pluralize }}
</div>
<div class="col-md-4">
<span class="badge">{{ group.posts.count }}</span> post{{ group.posts.count|pluralize }}
</div>
</div>
</div>
</a>
{% endfor %}
</div>
</div>
{% block pagination %}
{% if is_paginated %}
<ul class="pagination" style="display:inline-block">
{% if page_obj.has_previous %}
<li>«</li>
{% else %}
<li class="disabled"><span>«</span></li>
{% endif %}
{% for i in paginator.page_range %}
{% if page_obj.number == i %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li>{{ i }}</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li>»</li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
{% endif %}
{% endblock %}
{% endblock %}
The pagination code should be inside the col-md-8 div tag like below ::
{% extends "groups/group_base.html" %}
{% block pregroup %}
<div class="col-md-4">
<div class="content">
{% if user.is_authenticated %}
<h2>
Welcome back
#{{user.username }}
</h2>
{% endif %}
<h2>Groups</h2>
<p>Welcome to the Groups Page! Select a Group with a shared interest!</p>
</div>
{% if user.is_authenticated %}
<span class="glyphicon glyphicon-plus-sign"></span> Create New Group!
{% endif %}
</div>
{% endblock %}
{% block group_content %}
<div class="col-md-8">
<div class="list-group">
{% for group in object_list %}
<a class="list-group-item" href="{% url 'groups:single' slug=group.slug %}">
<h3 class="title list-group-item-heading">{{ group.name }}</h3>
<div class="list-group-item-text container-fluid">
{{ group.description_html|safe }}
<div class="row">
<div class="col-md-4">
<span class="badge">{{ group.members.count }}</span> member{{ group.members.count|pluralize }}
</div>
<div class="col-md-4">
<span class="badge">{{ group.posts.count }}</span> post{{ group.posts.count|pluralize }}
</div>
</div>
</div>
</a>
{% endfor %}
</div>
{% block pagination %}
{% if is_paginated %}
<ul class="pagination" style="display:inline-block">
{% if page_obj.has_previous %}
<li>«</li>
{% else %}
<li class="disabled"><span>«</span></li>
{% endif %}
{% for i in paginator.page_range %}
{% if page_obj.number == i %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li>{{ i }}</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li>»</li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
{% endif %}
{% endblock %}
</div>
{% endblock %}
I'm trying to make the forloop group the images into <li> of 6 plus a last li with remainder if the total number isn't a multiple of 6. Right now it doesn't do this correctly some of the tags aren't inside the li.
{% for movie in movies %}
{% if forloop.counter|divisibleby:6 %}
<li>
{% endif %}
{% if forloop.first %}
<li>
{% endif %}
<a href="{{ movie.get_absolute_url }}">
{% thumbnail movie.picture "158x215" as im %}
<img src="{{ im.url }}" alt="">
{% endthumbnail %}
<p>{{ movie.name }}</p>
</a>
{% if forloop.counter|divisibleby:6 %}
</li>
{% endif %}
{% ifequal forloop.counter 5 %}
<li>
{% endifequal %}
{% endfor %}
You can do something like this to create a new <li> element after every 6 iterations.
<li>
{% for movie in movies %}
<a href="{{ movie.get_absolute_url }}">
{% thumbnail movie.picture "158x215" as im %}
<img src="{{ im.url }}" alt="">
{% endthumbnail %}
<p>{{ movie.name }}</p>
</a>
{% if forloop.counter|divisibleby:6 %}
</li>
<li>
{% endif %}
{%endfor%}
</li>