I have a model Book which contains a CharField: 'category' which describes the genre of book and I want to display the information of books according to their genre.
I tried this:
{% for category in categories %}
<div class="row">
<div class="title-section mb-5 col-12">
<h2>Popular in {{category}}</h2>
</div>
</div>
<div class="row">
{% for book in books %}
{% if book.category == '{{category}}' %}
<div class="col-lg-4 col-md-6 item-entry mb-4">
<a href="#" class="product-item md-height bg-gray d-block">
<img src='/media/{{book.img}}' alt="Image" class="img-fluid">
</a>
<h2 class="item-title">{{ book.title }}</h2>
<strong class="item-price">Rs. {{ book.price }}</strong>
</div>
{% endif %}
{% endfor %}
</div>
{% endfor %}
models.py :
def main(request):
books = Book.objects.all()
categories = []
for book in books:
categories.append(book.category)
categories = list(set(categories))
return render(request, "index.html", {'books': books, 'categories': categories,})
But this is not working, it displayed only:
Popular in fiction
Popular in motivational
Popular in informative
Popular in teen
Popular in autobiography
No information of any books is displayed. I think there is problem in if condition please help me out!
Change this line
{% if book.category == '{{category}}' %}
To this
{% if book.category == category %}
Related
I am currently facing this problem with Django ListView. Basically, I need to filter some questions per topic and I would like to paginate the results.
My code is working perfectly about the queryset part (the results are showed correctly) but I am facing a problem with pagination.
Let's say I have so far 8 items in my query, if I choose to paginate_by = 10, it shows me just one page. If, otherwise, I choose to paginate by, let's say, 3, it shows me 3 pages to choose in the template (which is correct) but it shows me ALL the results of the query in my page.
I post some code to be more clear
models.py:
class Tag(models.Model):
name = models.CharField(max_length=300, unique=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def clean(self):
self.name = self.name.capitalize()
def __str__(self):
return self.name
class Question(models.Model):
post_owner = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=5000, default='')
body = tinymce_models.HTMLField()
tags = models.ManyToManyField(
Tag, related_name='tags')
viewers = models.ManyToManyField(
User, related_name='viewed_posts', blank=True)
views.py:
class TagQuestionsListView(ListView):
template_name = 'main/tag_questions.html'
paginate_by = 20
def get_queryset(self, **kwargs):
tag = Tag.objects.get(name=self.kwargs['name'])
questions = Question.objects.filter(tags=tag)
return questions
def get_contextdata(self, **kwargs):
context = super().get_context_data(**kwargs)
context['tag'] = Tag.objects.get(name=self.kwargs['name'])
context['questions'] = Question.objects.filter(
tags=context['tag'], is_deleted=False)
return context
template:
{% extends 'base.html' %}
{% load humanize %}
{% block title %}Domande su {{tag.name}}{% endblock title %}
{% block content %}
<style>
.text {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2; /* number of lines to show */
line-clamp: 2;
-webkit-box-orient: vertical;
}
</style>
<div class="card">
<div class="mt-3">
<h3 class="ms-2" style="display: inline;">Ultime {{ questions.count }} Domande</h3>
{% if request.user.is_authenticated %}
Fai una domanda
{% else %}
Fai una domanda
{% endif %}
</div>
<h5 class="ms-2">{{ total_questions.count }} domande totali </h5>
<hr>
{% for question in questions %}
<div class="row">
<div class="col-2 ms-2">
<p>{{ question.count_all_the_votes }} Voti</p>
<p>{{ question.count_answers }} Risposte</p>
<p>{{ question.calculate_viewers }} Visualizzazioni</p>
</div>
<div class="col-9">
<h5>{{question.title}}</h5>
<div class="text">
{{ question.body|striptags }}
</div>
{% for tag in question.tags.all %}
<a class="btn btn-sm btn-outline-primary m-1" href="{% url 'main:tag_questions' name=tag.name %}">{{tag.name}}</a>
{% endfor %}
<div class="float-end">
<a style="display: inline;" href="">{{question.post_owner}}</a>
{% if question.is_edited == False %}
<span style="display:inline;">creata {{question.created_at | naturaltime}}</span>
{% else %}
<span style="display:inline;"> modificata {{question.edited_time | naturaltime}} da <a style="display: inline;" href="">{{question.edited_by.username}}</a></span>
{% endif %}
</div>
</div>
</div>
<hr>
{% endfor %}
</div>
<div class="row mt-3">
<div class="col-lg-12">
<div class="card">
<div class="card-body">
<nav aria-label="Page navigation example">
<ul class="pagination">
{% if page_obj.has_previous %}
<li class="page-item"><a class="page-link" href="{% url 'main:tag_questions' name=tag.name %}?filter={{ filter }}&orderby={{ orderby }}&page={{ page_obj.previous_page_number }}">Precedente</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#">Precedente</a></li>
{% endif %}
{% for i in paginator.page_range %}
<li class="page-item {% if page_obj.number == i%} active {% endif %} %} "><a class="page-link" href="?filter={{ filter }}&orderby={{ orderby }}&page={{ i }}">{{i}}</a></li>
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item"><a class="page-link" href="{% url 'main:tag_questions' name=tag.name %}?filter={{ filter }}&orderby={{ orderby }}&page={{ page_obj.next_page_number }}">Prossima</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#">Prossima</a></li>
{% endif %}
</ul>
</nav>
</div>
</div>
</div>
{% endblock content %}
With this I want my comment converter to answer.
You have to use page_obj instead questions in your template.
<--! ⬇️⬇️⬇️ -->
{% for question in page_obj %}
<div class="row">
<div class="col-2 ms-2">
<p>{{ question.count_all_the_votes }} Voti</p>
<p>{{ question.count_answers }} Risposte</p>
<p>{{ question.calculate_viewers }} Visualizzazioni</p>
</div>
<div class="col-9">
<h5>{{question.title}}</h5>
<div class="text">
{{ question.body|striptags }}
</div>
{% for tag in question.tags.all %}
<a class="btn btn-sm btn-outline-primary m-1" href="{% url 'main:tag_questions' name=tag.name %}">{{tag.name}}</a>
{% endfor %}
<div class="float-end">
<a style="display: inline;" href="">{{question.post_owner}}</a>
{% if question.is_edited == False %}
<span style="display:inline;">creata {{question.created_at | naturaltime}}</span>
{% else %}
<span style="display:inline;"> modificata {{question.edited_time | naturaltime}} da <a style="display: inline;" href="">{{question.edited_by.username}}</a></span>
{% endif %}
</div>
</div>
</div>
<hr>
{% endfor %}
So, if you define attribute paginate_by , than ListView(django docs) adds a paginator and page_obj to the context. To allow the users to navigate between pages, add links to the next and previous page, in your template.
I am trying to create a template for a blog landing page. Basically, I am trying to extend certain features from my base template, so I have two block tags that I want to appear at different parts of the page. Here is the first block tag;
{% extends 'index.html' %}
{% block content %}
{% for politic in politics %}
<div class="post-entry-1 col-lg-4 box mx-1">
<img src="{{politic.image.url}}" alt="" class="post_img">
<div class="post-meta">
<span class="date">{{politic.category}}</span>
<span class="mx-1">•</span>
<span>{{politic.created_at}}</span>
</div>
<h2 class="mb-2">{{politic.title}}</h2>
<span class="author mb-3 d-block">Ole Pundit</span>
<p class="mb-4 d-block">{{politic.body|truncatewords:75}}</p>
</div>
{% endfor %}
{% endblock %}
But once the number of blog posts uploaded (politics.count) reaches 4, I want the for loop in the first block tag to break. And the following block tag to be executed;
{% block sidepolitics %}
{% if politics.count > 4 %}
{% for politic in politics %}
<div class="post-entry-1 border-bottom">
<div class="post-meta">
<span class="date">{{politic.category}}</span>
<span class="mx-1">•</span>
<span>{{politic.created_at}}</span>
</div>
<h2 class="mb-2">
<a href="single-post.html">{{politic.title}}
</a>
</h2>
<span class="author mb-3 d-block">Ole Pundit</span>
</div>
{% endfor %}
{% endif %}
{% endblock %}
Meaning the maximum number of blogposts that should follow the first layout is four, and the rest should all follow the second layout.
Both blog tags are nested under the political.html file below
{% extends 'index.html' %}
{% block content %}
{% for politic in politics %}
<div class="post-entry-1 col-lg-4 box mx-1">
<img src="{{politic.image.url}}" alt="" class="post_img">
<div class="post-meta">
<span class="date">{{politic.category}}</span>
<span class="mx-1">•</span>
<span>{{politic.created_at}}</span>
</div>
<h2 class="mb-2">{{politic.title}}</h2>
<span class="author mb-3 d-block">Ole Pundit</span>
<p class="mb-4 d-block">{{politic.body|truncatewords:75}}</p>
</div>
{% endfor %}
{% endblock %}
{% block sidepolitics %}
{% if politics.count > 4 %}
{% for politic in politics %}
<div class="post-entry-1 border-bottom">
<div class="post-meta">
<span class="date">{{politic.category}}</span>
<span class="mx-1">•</span>
<span>{{politic.created_at}}</span>
</div>
<h2 class="mb-2">
<a href="single-post.html">{{politic.title}}
</a>
</h2>
<span class="author mb-3 d-block">Ole Pundit</span>
</div>
{% endfor %}
{% endif %}
{% endblock %}
And here is my base template **index.html;
<div class="d-flex align-items-end">
{% block content %}
{% endblock %}
</div>
</div>
<div class="col-md-3">
{% block sidepolitics %}
{% endblock %}
</div>
**view.py
from django.shortcuts import render
from .models import Post, Politics
from django.views.generic import DetailView
# Create your views here.
def index(request):
return render(request, 'index.html')
def allposts(request):
posts = Post.objects.all()
return render(request, 'allposts.html', {'posts':posts})
def political(request):
politics = Politics.objects.all()
return render(request, 'political.html', {'politics':politics})
def post(request, pk):
posts = Post.objects.get(id=pk)
return render(request, 'posts.html', {'posts':posts})
The problem is, for both for loops the application starts iterating from the very beginning. How can I make the first for loop to iterate only up to the fourth count, and the second for loop to pick up right where the first loop leaves off.
Firstfully, if you want to count objects, you need to use .count in template:
{% if politics > 4 %} # good for integers or similar
{% if politics.count > 4 %} # good for querysets
Secondly, you need to understand standard pythonish for loops because {% for politics in politics %} just makes absolutely no sense. It works like this:
{% for politic in politics %} # usually it's like this: {% for SINGULAR in PLURAL %}
otherwise you are overriding politics variable and it should not work, at least not good.
Second loop makes no sense at all, I guess you don't need it.
With that said and your edits, use forloop.counter. It returns int with the current loop round. Here's hint:
{% for item in item_list %}
{{ forloop.counter }} # starting index 1
{{ forloop.counter0 }} # starting index 0
{% endfor %}
Instead of {% if politics.count > 4 %} that now I understand you don't need, use above logic. In first loop:
{% for politic in politics %}
{% if forloop.counter < 5 %}
# whole first for loop here
{% else %}
# whole second for loop here
{% endif %}
{% endfor %}
I know this is my first question and I wouldn't be like writing it here, but I have a problem which I couldn't handle for 2 days now.
I am writing an app in Django, and my goal is to handle requests from google books API and display books in the template which I did.
I wrote a function like this
services.py
from googleapiclient.discovery import build
import json
def get_books_data(query):
"""Retriving data from google books API"""
service = build('books',
'v1',
developerKey=API_KEY
)
request = service.volumes().list(q=query)
response = request.execute()
book_list = [response['items'][item]['volumeInfo']
for item in range(len(response['items']))]
return book_list
I get a list of key: value pairs representing ten books from API.
I passed them into a template like this
views.py
def search(request):
query = request.GET.get('q')
books = get_books_data(query)
context = {
'books': books
}
return render(request, 'books_list.html', context)
This is how book_list.html looks like.
list_book.html
{% extends 'base.html' %}
{% load static %}
{% block content%}
{% for book in books %}
<div class="row">
<div class="col-lg-8 mx-auto">
<ul class="list-group shadow">
<li class="list-group-item">
<div class="media align-items-lg-center flex-column flex-lg-row p-3">
<div class="media-body order-2 order-lg-1">
<h5 class="mt-0 font-weight-bold mb-2">{{ book.title }}</h5>
<p class="font-italic text-muted mb-0 small">{{ book.subtitle }}</p>
{% for identifier in book.industryIdentifiers %}
<p class="font-italic text-muted mb-0 small">{{ identifier.type }} : {{ identifier.identifier }}</p>
{% endfor %}
<p class="font-italic text-muted mb-0 small">Language: {{ book.language }}</p>
<p class="font-italic text-muted mb-0 small">Published date: {{ book.publishedDate }}</p>
<div class="media-body order-2 order-lg-1">
{% if book.authors %}
<h6 class="font-weight-bold my-2">Authors:</h6>
{% for author in book.authors %}
<p class="font-italic text-muted mb-0 small">{{ author }}</p>
{% endfor %}
{% endif %}
</div>
{% if book.pageCount %}
<div class="d-flex align-items-center justify-content-between mt-1">
<h6 class="font-weight-bold my-2">Number of pages: {{book.pageCount}}</h6>
</div>
{% endif %}
</div>
{% if book.imageLinks %}
<img class="thumbnail" src="{{book.imageLinks.thumbnail}}" alt="">
{% else %}
<img class="thumbnail2" src="{% static 'images/placeholder4.png'%}" alt="">
{% endif %}
</div>
<form action="." method="post">
{% csrf_token %}
<button type="submit" class="btn btn-primary">ADD THIS BOOK TO YOUR BOOKSHELF</button>
</form>
</li>
</ul>
</div>
</div>
{% endfor %}
{% endblock content %}
And last part of my task is to have a button in each card with a book, I can use to save a particular book from API to the database.
I am a beginner in Django, and I've tried to use forms, I've read, I could use Django Rest Framework somehow but really, I don't have an idea, how I could approach this problem.
Please, Can you help me?
Than you in advance.
I built a django powered webapps,where I used a model field called average CGPA(avg_cgpa) which is a DecimalField in Django model. Also I used a for loop on controller/template to generate all separate data about a student.Now my intention is to compare avg_cgpa data for every row of model to generate a new tag.Where it will be print different result for each student.
Like, if avg_cgpa > 2.00 it will be print pass,otherwise fail !
I did tried as you have seen on template but its not working,please come up with your helpfull answer.
(Django model here)
class Management(models.Model):
student_id = models.CharField(max_length=100)
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
father_name = models.CharField(max_length=200)
mother_name = models.CharField(max_length=200)
Present_address = models.TextField(max_length=400)
Permanent_address = models.TextField(max_length=400)
contact = models.CharField(max_length=11)
avg_cgpa = models.DecimalField(max_digits=20,decimal_places=2)
def __str__(self):
return self.student_id
(Here is the template)
{% load static %}
{% include 'base.html' %}
{% block content %}
{% include 'navbar.html' %}
{% include 'banner.html' %}
<div class = "container">
<div class="row">
{% for x in student %}
<div class="col-md-4">
<div class="card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title"><strong>ID : </strong> {{ x.student_id }}</h5>
<hr class="my-4">
<img class="card-img-top" src="{% static "images/hat.png" %}"><hr class="my-4">
<h6 class="card-subtitle mb-2 text-muted"><strong><i class="far fa-user-circle"></i> </strong> {{ x.first_name }} {{ x.last_name }}</h6>
<hr class="my-4">
<p class="card-text">Father's Name : <strong>{{ x.father_name }}</strong></p>
<p class="card-text">Mother's Name : <strong>{{ x.mother_name }}</strong></p>
<p class="card-text">Address : <strong>{{ x.Permanent_address }}</strong></p>
<p class="card-text"><strong><i class="fas fa-phone"></i> {{ x.contact }}</strong> </p>
<p class="card-text">Avg CGPA : <strong>{{ x.avg_cgpa }}</strong></p>
{% if x.avg_cgpa > "2" %}
<p class="card-text">Condition : <strong>Pass</strong></p>
{% endif %}
</div>
</div>
</br>
</div>
{% endfor %}
</br>
</div>
{% include 'footer.html' %}
{% endblock%}
I did tried if condition within for loop,but no result as outcome.Is it possible to retrieve data by comparing model data in django ?
I would consider adding a property to your model that returns whether it is a pass or not
class Management(models.Model):
#property
def passed(self):
return self.avg_cgpa > 2
This can then be used in the template {% if x.passed %}, it can also be used in other parts of your code and is a bit more readable
long-time lurker for this website, but I finally decided to join the community.
I have a quick question on some of my code. I took a job this year for my university developing a website for the journalist department. The website was being built the previous year by another student using Django 1.8, python 2, and everything else that comes with that. I knew a decent amount about these languages, and I have learned a lot testing out different methods for hours on end. However, there is one thing I am having trouble with that I have researched for forever.
Basically, for my website, I have different "sections" for different pages of articles. These articles have many traits. One trait is called "section" and this section has the names of the pages. So for example:
One page is named "look". I can call my code and display all of my featured_articles. HOWEVER, I am trying to only display the articles where the name of the section equals "look".
Here is my current code. Any ideas? I have tried many things but I can't get it to work properly. For loops, if statements, different HTML processes, different pages in django, etc...
{% for article, section in featured_articles %}
<div class="media panel panel-default">
<div class="panel-body">
<div class="media-left">
<a href="articles/{{ article.url }}">
<img class="media-object thumbnail-featured"
src="{{ article.image }}">
</a>
</div>
<div class="media-body">
<a href="articles/{{ article.url }}">
<h3 class="media-heading">{{ article.title }}</h3>
</a>
<!-- TODO figure out how to iterate through the authors field, manytomany -->
{% for contributor in article.authors.all %}
<p>{{ section.name }} |
{{contributor}}</p>
{% endfor %}
<p>{{article.preview}}</p>
</div>
</div>
</div>
{% endfor %}
Thank you for any help!!
Overall, it is a not such a good idea. You are sending all data to the template engine and doing the filtering there?
Why not filter it in the view function / view class and then return that data inside a template variable and then render in the front end?
def detail(request, poll_id):
filtered_data = .......objects.get(name='look')
return render(request, 'polls/detail.html', {'look_data': filtered_data})
{% for article, section in look_data %}
<div class="media panel panel-default">
.... blah blah blah
</div>
{% endfor %}
As I understand, you just need to add if statement:
{% for article, section in featured_articles %}
{% if section.name == 'look' %}
<div class="media panel panel-default">
<div class="panel-body">
<div class="media-left">
<a href="articles/{{ article.url }}">
<img class="media-object thumbnail-featured"
src="{{ article.image }}">
</a>
</div>
<div class="media-body">
<a href="articles/{{ article.url }}">
<h3 class="media-heading">{{ article.title }}</h3>
</a>
<!-- TODO figure out how to iterate through the authors field, manytomany -->
{% for contributor in article.authors.all %}
<p>{{ section.name }} |
{{ contributor }} </p>
{% endfor %}
<p>{{article.preview}}</p>
</div>
</div>
</div>
{% endif %}
{% endfor %}