How can I compare model saved data in django from controller? - python

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

Related

Pagination in Django ListView when using get_context_data

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.

Error when listing out a user's followers

I am trying to add a notifications feature to my social media platform. Part of this involves adding a notifications logo to my navbar at the top of my website which will display the number of unseen notifications a logged-in user has.
When I run my server, I receive a NameError:
NameError
Here is part of my navbar.html:
{% load custom_tags %}
(...)
{% if user.is_authenticated %}
<div class="nav-item dropdown">
<a class="nav-link dropdown-toggle text-dark" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false"><i class="fas fa-user"></i></a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item" href="{% url 'profile' request.user.profile.pk %}">Profile</a></li>
<li><a class="dropdown-item" href="{% url 'account_logout' %}">Sign Out</a></li>
</ul>
</div>
<div class="nav-item">
{% show_notifications %}
{% endif %}
</div>
</div>
</nav>
Here is my show_notifications.html:
<div class="dropdown">
<span class="badge bg-primary notification-badge">{{ notifications.count }}</span>
<div class="dropdown-content d-none" id="notification-container">
{% for notification in notifications %}
{% if notification.post %}
{% if notification.notification_type == 1 %}
<div class="dropdown-item-parent">
#{{ notification.from_user }} liked your post
<span class="dropdown-item-close">×</span>
</div>
{% elif notification.notification_type == 2 %}
<div class="dropdown-item-parent">
#{{ notification.from_user }} commented on your post
<span class="dropdown-item-close">×</span>
</div>
{% endif %}
{% elif notification.comment %}
{% if notification.notification_type == 1 %}
<div class="dropdown-item-parent">
#{{ notification.from_user }} liked on your comment
<span class="dropdown-item-close">×</span>
</div>
{% elif notification.notification_type == 2 %}
<div class="dropdown-item-parent">
#{{ notification.from_user }} replied to your comment
<span class="dropdown-item-close">×</span>
</div>
{% endif %}
{% else %}
<div class="dropdown-item-parent">
#{{ notification.from_user }} has started following you
<span class="dropdown-item-close">×</span>
</div>
{% endif %}
{% endfor %}
</div>
</div>
Here is my custom_tags.py:
from django import template
from academiciesocial.models import Notification
register = template.Library()
#register.inclusion_tag('social/show_notifications.html', takes_context=True)
def show_notifications(context):
request_user = context['request'].user
notifiations = Notification.objects.filter(to_user=request_user).exclude(user_has_seen=True).order_by('-date')
return {'notifications': notifications}
The final notifications has been marked as "is not defined (PylancereportUndefinedVariable)".
My Notifications class from my models.py:
class Notification(models.Model):
# 1 = Like, 2 = Comment, 3 = Follow
notification_type = models.IntegerField()
to_user = models.ForeignKey(User, related_name='notification_to', on_delete=models.CASCADE, null=True)
from_user = models.ForeignKey(User, related_name='notification_from', on_delete=models.CASCADE, null=True)
post = models.ForeignKey('Post', on_delete=models.CASCADE, related_name='+', blank=True, null=True)
comment = models.ForeignKey('Comment', on_delete=models.CASCADE, related_name='+', blank=True, null=True)
date = models.DateTimeField(default=timezone.now)
user_has_seen = models.BooleanField(default=False)
I am fairly new to this so I would greatly appreciate the exact step-by-step answers to the problem :)
there is typo in your code.
It should be "notifications" you made it "notifiations"

How to post data from google books API to your Book model using Django

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.

if condition is not working with string variables in django template

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 %}

i am getting an error saying category matching query does not exist

The voting proceess is working fine with this code. The problem is only when redirecting after voting the options.
Exception Type:DoesNotExist
Exception Value:
Category matching query does not exist.
category = Category.objects.get(slug=slug)
urls.py
path('<slug>/',views.options,name='options'),
path('<slug>/vote/', views.vote, name='vote'),
views.py
def home(request):
categories = Category.objects.filter(active=True)
return render(request,'rank/base.html',{'categories': categories,'title':'TheRanker'})
def options(request,slug):
category = Category.objects.get(slug=slug)
options = Option.objects.filter(category=category)
return render(request,'rank/options.html',{'options':options,'title':'options'})
def vote(request,slug):
option = Option.objects.get(slug=slug)
if Vote.objects.filter(slug=slug,voter_id=request.user.id).exists():
messages.error(request,'You Already Voted!')
return redirect('rank:options',slug)
else:
option.votes += 1
option.save()
voter = Vote(voter=request.user,option=option)
voter.save()
messages.success(request,'Voted!')
return redirect('rank:options',slug)
options.html
{% extends "rank/base.html" %}
<title>{% block title %}{{title}}{% endblock title%}</title>
{% load bootstrap4 %}
{% block content %}
<center><br>
<center>{% bootstrap_messages %}</center>
<ol type="1">
{% for option in options %}
<div class="col-lg-6 col-md-6 mb-6">
<div class="card h-100">
<div class="card-body">
<b><li>
<img src="/media/{{option.image}}" width="200" height="100">
<h4>{{option.name}}
</h4>
<h5 class="card-text">{{ option.details}}</h5>
<h5>{{ option.votes }} votes</h5>
<form action="{% url 'rank:vote' option.slug %}" method="post">
{% csrf_token %}
<input type="submit" class="btn btn-success" value="Vote" >
</form>
</li></b>
</div>
<div class="card-footer">
<small class="text-muted"></small>
</div>
</div>
</div>
{% endfor %}
</ol>
</center>
{% endblock content%}
You're confusing categories and options. The form sends the slug of the option, but then you redirect to the categories view using the same slug. But those are two different models.

Categories