How do I get all candidate in a position - python

Am trying to query every candidate that belong to a specific position and loop through it using the django template in my html. If I have just one position/poll all candidate will display in my frontend, but once i add another position/poll then the list of the candidate will not display again
def index(request):
context = {}
instruction = ""
positions = Position.objects.order_by('priority').all()
for position in positions:
candidates = Candidate.objects.filter(position=position)
for candidate in candidates:
votes = Votes.objects.filter(candidate=candidate).count()
if position.max_vote > 1:
instruction = "You may select up to " + str(position.max_vote) + " candidates"
else:
instruction = "Select only one candidate"
context = {
'positions': positions,
'candidates': candidates,
'votes': votes,
'instruction': instruction
}
return render(request, 'poll/index.html', context)
{% block content %}
<div class="row">
<div class="mt-5">
{% for p in positions %}
{{ instruction }}
<h1>{{ p.name }}</h1>
<p>{{ p.description }}</p>
{% for c in candidates %}
<h1>{{ candidate.fullname }}</h1>
{% endfor %}
{% endfor %}
</div>
</div>
{% endblock %}

Well, as much I understand you are querying objects inside the for loop and you are not storing the result of each iteration, whenever the next iterations happen, that overwrite the candidates and votes variable...

Related

Django pass family in template inside for cycle

In a simple view I pass a family in template like this:
def page(request):
family= Author.objects.all()
return render(request, "myapp/page.html", {'family':family})
and I render in template like this:
{% for item in family %}
{{ item.pk }}
{% endfor %}
But, if I put my family inside a for cycle; for example:
def page(request):
family = []
for i in range(5):
family= Author.objects.filter(name='John')[i]
return render(request, "myapp/page.html", {'family':family})
it not render anything in template...
Any idea?
EDIT 1
I have more users in my app, every user has different blog and every blog has different post...
So when user is logged i need to show his blog and for every blog show last 5 post.
I do:
#login_required
def page(request):
user = request.user.id
numblog = Blog.objects.filter(user_id=user).aggregate(c=Count('id'))
for i in range(numblog['c']):
blogquery = Blog.objects.filter(user_id=user)[i]
postquery = Post.objects.filter(blog_id=blogquery.pk)[:5]
return render(request, "myapp/page.html", {'blogquery ':blogquery,'postquery ':postquery })
expected result in template:
{% for b in blogquery %}
{{ b.name }} ### here name of blog
{% for p in postquery %}
{% if p.blog_id == b.pk %}
{{ p.content }} ### here last 5 post of THAT blog
{% endif %}
{% endfor %}
{% endfor %}
EDIT 2
In a view, if I print result it work but not render in template
#login_required
def page(request):
user = request.user.id
numblog = Blog.objects.filter(user_id=user).aggregate(c=Count('id'))
for i in range(numblog['c']):
blogquery = Blog.objects.filter(user_id=user)[i]
postquery = Post.objects.filter(blog_id=blogquery.pk)[:5]
for p in postquery:
print (blogquery.pk, p.pk)
return render(request, "myapp/page.html", {'blogquery ':blogquery,'postquery ':postquery })
It is surprising how you don't understand that repeatedly assigning to the same variable within a loop will just give you the last value.
But nevertheless, you don't need any of this code. You should just follow the relationship in the template.
#login_required
def page(request):
blogs = Blog.objects.filter(user=user).prefetch_related('post_set')
return render(request, "myapp/page.html", {'blogs ': blogs })
{% for blog in blogs %}
{{ blog.name }}
{% for post in blog.post_set.all|slice:"5" %}
{{ post.content }}
{% endfor %}
{% endfor %}
(You haven't shown your models so I presume the related_name from Blog to Post is called post_set, change as necessary.
UPDATE
That's not correct. You don't need to use for loop. If you need to get the last 5 rows you can do this i.e.:
def page(request):
family= Author.objects.all().order_by('-pk')[:5]
return render(request, "myapp/page.html", {'family':family})
another approach is to limit the results in your template:
{% for item in family %}
{% if forloop.counter < 6 %}
{{ item.pk }}
{% endif %}
{% endfor %}

Django disable a link if list returns empty

I don't want to display a link if the list returns empty.
template.html
{% for item in cart %}
<h1>{{ item.product.product_title }}</h1>
Remove item
{% empty %}
<p>No items in cart</p>
{% endfor %}
{% if item is not None %}
<p>
Checkout
</p>
{% endif %}
views.py
def cartview(request):
if request.user.is_authenticated():
cart = Cart.objects.filter(user=request.user.id, active=True)
orders = ProductOrder.objects.filter(cart=cart)
#total = 0
count = 0
for order in orders:)
count += order.quantity
context = {
'cart': orders,
'count': count,
}
return render(request, 'store/cart.html', context)
else:
return redirect('index:index')
I want to hide checkout link if the cart list is empty. putting it in the for loop would make the link appear many times. I want to display checkout button only once.
Instead of 'item' check for 'cart' in the template.
{% if cart %}
<p>
Checkout
</p>
{% endif %}

django sort dict after query

have a table with websites and a many to one table with descriptions
trying to get a list, firstly getting the latest descriptions and then displaying them ordered by the content of the descriptions...
have the following in views.py
def category(request, category_name_slug):
"""Category Page"""
context_dict = {}
try:
category = Category.objects.get(slug=category_name_slug)
subcategory = SubCategory.objects.filter(category=category)
websites = Website.objects.filter(sub_categories=subcategory, online=True, banned=False)
sites = websites
descriptions = WebsiteDescription.objects.prefetch_related("about")
descriptions = descriptions.filter(about__in=sites)
descriptions = descriptions.order_by('about', '-updated')
descs = []
last_site = "" # The latest site selected
# Select the first (the latest) from each site group
for desc in descriptions:
if last_site != desc.about.id:
last_site = desc.about.id
desc.url = desc.about.url
desc.hs_id = desc.about.id
desc.banned = desc.about.banned
desc.referral = desc.about.referral
descs.append(desc)
context_dict['descs'] = descs
context_dict['websites'] = websites
context_dict['subcategory'] = subcategory
context_dict['category'] = category
except SubCategory.DoesNotExist:
pass
return render(request, 'category.html', context_dict)
this gives me a list with sites and their latest descriptions, so i have the following in category.html
{% if category %}
<h1>{{ category.name }}</h1>
{% for subcategory in category.subcategory_set.all %}
{{ subcategory.name }} ({{ subcategory.website_set.all|length }})
{% endfor %}
{% if descs %}
{% load endless %}
{% paginate descs %}
{% for desc in descs|dictsortreversed:"description"|dictsortreversed:"officialInfo" %}
<ul id='list' class='linksteps'>
<a href="/{{ desc.about_id }}" rel="nofollow" target="_blank">
<img src="/static/screenshots/{{ desc.about_id }}.png" />
</a>
<li><h3>{{ desc.about_id }}{% if desc.title %} - {{ desc.title }} {% endif %}</h3>
{% if desc.description %}<b>Description: </b>{{ desc.description }}
<br />{% endif %} {% if desc.subject %}<b>Keywords: </b>{{ desc.subject }}
<br />{% endif %} {% if desc.type %}<b>Type: </b>{{ desc.type }}
<br />{% endif %} {% if desc.officialInfo %} {% if desc.language %}<b>Language: </b>{{ desc.language }}
<br />{% endif %} {% if desc.contactInformation %}<b>Contact info: </b>{{ desc.contactInformation }}
<br />{% endif %}
{% else %}
{% endif %}
</li>
</ul>
</div>
{% endfor %}
{% show_pages %}
{% else %}
<strong>No websites currently in category.</strong>
{% endif %}
{% else %}
The specified subcategory {{ category_name }} does not exist!
{% endif %}
Initially i used dictsort
{% for desc in descs|dictsortreversed:"description"|dictsortreversed:"officialInfo"|dictsortreversed:"referral" %}
to give me the list in the desired order, so i was all happy ;)
Then however i decided i needed some pagination because the lists became too long.
django-endless-pagination works fine and does what its supposed too, however it splits up my list before the dictsort kicks in.
is there a way to sort before pagination happens and after i ordered_by at the initial query to have the latest descriptions selected?
much obliged
EDIT:
not getting any answers so my question might not be clear.
as far as i understand i need to sort the values in context_dict at the end in views.py replacing the dictsort as in the template
SOLVED:::
doing this did the trick for me to replace the dictsort.
descs1 = sorted(descs, key=operator.attrgetter('referral', 'officialInfo', 'description'), reverse=True)
context_dict['descs'] = descs1
SOLVED:::
doing this did the trick for me to replace the dictsort.
descs1 = sorted(descs, key=operator.attrgetter('referral', 'officialInfo', 'description'), reverse=True)
context_dict['descs'] = descs1

badge notification by the number of new matches

I am trying to get a batch notification to work, but the badge throws several badges with the below code, and it does not show the number. I want the badge to display the number of content within several posts matches with an interest.
I am still a beginner at django, so please bear over with me, if this is a total bad approach.
interest.html
{% for item in interest %}
<ul class='nav nav-pills nav-stacked'>
<li><a href='/'>
<span class='badge pull-right'>
{% for word in post %}
{% if word == interest %}
{{ word.as_number }}
{% else %}
0
{% endif %}
{% endfor %}
</span>
{{ item.interest }}
</a></li>
</ul>
{% endfor %}
context_processors.py
def user_interest(request):
interest = Interests.objects.all()
interests_form = InterestsForm(request.POST or None)
post = Posts.objects.all()
if interests_form.is_valid():
new_interest = interests_form.save(commit=False)
new_interest.save()
#return HttpResponseRedirect('/')
#apparently it is not needed here
return {'interest': interest,
'interests_form': interests_form,
'post': post,
}
models.py
class Interests(models.Model):
interest = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True)
I'm not fully understanding, but part of your problem may be this part:
{% if word == interest %}
You're comparing a particular Post with all of your Interests (since 'interest' = Interests.objects.all()). At the very least I would change that to:
{% if word == item %}
As this iterates through your interest list (using 'item') and compares it to each 'word' in your post list.

dynamically connecting Django Q objects with AND and OR

I want users to be able to query my database via several different parameters (name, year, etc), dynamically add more fields, and join them with boolean operators; the net result would be something like "year = 1900 AND name = chicken AND location = San Francisco." I think I'm doing something wrong, since it's not returning anything, even when I try just one field with a value that I know matches some data (e.g., I can get objects back when I use .filter() from the Django shell). Anyone know how I can fix it?
Relevant view (ignore the sloppy indentation, I didn't want to go through and fix all of it, but it's right in my actual code):
class BaseSearchFormSet(BaseFormSet):
def clean(self):
if any(self.errors):
return self.errors
queries = []
valid_courses = ["appetizer","main","dessert"]
valid_period = re.compile(r'\d\d\d0-\d\d\d5|\d\d\d5-\d\d\d0')
valid_year = re.compile(r'\d{4}')
multi_rows = ["year","period","course"]
for x in xrange(0,self.total_form_count()):
form = self.forms[x]
query = form.cleaned_data.get("query")
row = form.cleaned_data.get("row")
if query in queries and row not in multi_rows:
raise forms.ValidationError("You're already searching for %s.")
queries.append(query)
if row == "course" and query.lower() not in valid_courses:
raise forms.ValidationError("%s is not a valid course option."%(form.cleaned_data["query"]))
if row == "period" and not re.match(valid_period,query):
raise forms.ValidationError("%s is not a properly formatted period. Valid five-year periods span either the first or second half of a decade. For example: 1910-1915, 1925-1930."%(form.cleaned_data["query"]))
if row == "year" and not re.match(valid_year,query):
raise forms.ValidationError("Please enter a four-digit year.")
def search(request):
errors = []
searchFormSet = formset_factory(F.SearchForm, extra=1,formset=BaseSearchFormSet)
if request.GET:
formset = searchFormSet(request.GET)
forms = []
if formset.is_valid():
for x in xrange(0,formset.total_form_count()):
form = {}
form["row"]= formset[x].cleaned_data.get("row",None)
form["query"] = formset[x].cleaned_data.get("query",None)
form["bools"] = formset[x].cleaned_data.get("bools",None)
if form["query"]:
q = form["query"]
else:
errors.append("no query found")
if form["row"]:
row = form["row"]
else:
errors.append("no row found")
filter_keys = {"dish_name":Q(dish__name__icontains=q),
"regex":Q(dish__full_name__regex=r'%s'%(q)),
"course":Q(dish__classification=q.lower()),
"year":Q(page__menu_id__year__exact=q),
"period":Q(page__menu_id__period__exact=q),
"location":Q(page__menu_id__location__icontains=q),
"restaurant":Q(page__menu_id__restaurant__icontains=q)}
forms.append(form)
final_query=Q()
def var_reduce(op,slice):
if op == "and":
return reduce(lambda x,y: x & y,slice)
elif op == "or":
return reduce(lambda x,y: x | y,slice)
for x in xrange(len(forms)):
try:
try:
if final_query:
slice = [final_query,filter_keys[forms[x]["row"]],filter_keys[forms[x+1]["row"]]]
else:
slice = [filter_keys[forms[x]["row"]],filter_keys[forms[x+1]["row"]]]
final_query = var_reduce(forms[x]["bools"],slice)
except IndexError:
if final_query:
slice = [final_query,filter_keys[forms[x]["row"]]]
else:
slice = [filter_keys[forms[x]["row"]]]
final_query = var_reduce(forms[x]["bools"],slice)
items = MenuItem.objects.filter(final_query)
return render_to_response("search_results.html",{"items":items,"formset":formset})
except KeyError as e:
errors.append(e)
formset = searchFormSet(None)
return render_to_response("search_page.html",{"errors":errors,"formset":formset})
else:
formset = searchFormSet(None)
return render_to_response("search_page.html",{"errors":errors,"formset":formset})
else:
formset = searchFormSet(None)
return render_to_response("search_page.html",{"formset":formset})
models:
from django.db import models
class MenuItem(models.Model):
def format_price(self):
return "${0:0<4,.2f}".format(float(self.price))
def __unicode__(self):
return self.dish
dish=models.OneToOneField('Dish',to_field='mk')
price=models.CharField(max_length=5,blank=True)
page=models.OneToOneField('MenuPage')
mk=models.CharField(max_length=10,unique=True)
formatted_price = property(format_price)
class Menu(models.Model):
def period(self):#adapted from http://stackoverflow.com/questions/2272149/round-to-5or-other-number-in-python
try:
p=int(10*round(float(int(self.year))/10))
if p < self.year:
return "%s-%s"%(p,p+5)
else:
return "%s-%s"%(p-5,p)
except (ValueError,TypeError):
return ""
def __unicode__(self):
if self.restaurant:
return self.restaurant
else:
return self.mk
restaurant=models.TextField(unique=False,blank=True,null=True)
year=models.CharField(max_length=4,unique=False,blank=True,null=True)
location=models.TextField(unique=False,blank=True,null=True)
status=models.CharField(unique=False,max_length=20)
mk=models.CharField(max_length=8,unique=True,primary_key=True)
period=property(period)
language = models.CharField(unique=False,max_length=30)
#objects=MenuManager()
class MenuPage(models.Model):
mk=models.CharField(max_length=10,unique=True)
menu_id=models.OneToOneField("Menu",to_field='mk')
#objects=MenuPageManager()
class Dish(models.Model):
def __unicode__(self):
return self.name
full_name = models.TextField()
name=models.CharField(unique=True,max_length=255)
mk=models.CharField(max_length=10,unique=True)
class Classification(models.Model):
def __unicode__(self):
if self.classification:
return self.classification
else:
return "none"
dish=models.OneToOneField('dish',to_field='name')
classification=models.CharField(unique=False,max_length=9)
mk=models.CharField(max_length=10,primary_key=True)
html of my search page:
{% extends "base.html" %}
{% block style %}
<link rel="stylesheet" type="text/css" href="/static/search_style.css" />
{% endblock %}
{% block java %}
<script type="text/javascript" src="/static/searches.js"></script>
{% endblock %}
{% block title %}Search{% endblock %}
{% block head %}Search{% endblock %}
{% block content %}
{% autoescape off %}
<div id="searches">
<form id="search" action="" method="get">
<table border="0" cellpadding="0" cellspace="0">
<tbody class="search">
{% for form in formset.forms %}
<tr>
<td class="row">{{ form.row }}</td>
<td class="query">{{ form.query }}</td>
<td class="bool">{{ form.bools }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ formset.management_form }}
<input type="submit" value="Submit" id="submit">
</form>
</div>
{% if formset.errors or errors %}
<div id="errors">
<h3>The following errors were encountered while trying to submit your search:</h3>
{% for x,y in formset.errors.items %}
<p>{{ x }} : {{ y }}</p>
{% endfor %}
{{ errors }}
</div>
{% endif %}
<div id="notes">
<p>Searching by dish names, locations, and restaurants is case-insensitive.</p>
<p>Searching by course uses case-insensitive exact matching. Valid courses are Appetizer, Main, and Dessert.</p>
<p>Years should be entered YYYY. Five-year periods span either the first or second half of a decade, and should be entered YYYY-YYYY. Example valid five-year periods are 1900-1905, 1995-2000, etc.</p>
<p>Regular expression search follows MySQL regular expression syntax, as described here.</p>
</div>
{% endautoescape %}
<br /><br /><br /><br /> <br /><br /><br />
{% endblock %}
{% block footer %}
<div id="warning">
<p>NOTE: This site and the information it contains are still in development. Some information may be missing or inaccurate.</p>
</div>
<div class="credits">
Created and maintained by Sam Raker and Rachel Rakov
<br />
Data graciously provided by What's on the Menu?
</div>
{% endblock %}
Sorry, my original post was more than you needed. To clarify, all you should need to do is:
Q(year__icontains=year_input_variable) | Q(city__icontains=city_input_variable) & Q(name__icontains=name_input_variable)
Use & for and, | for or.
What I had posted earlier is for if a query contains multiple words, it would either check to see if all of the words matched using operator.and or if any of the words matched using operator.or.

Categories

Resources