Python Django Subcategory - python

I want to print the subcategory names of each Main Category. The below code is now showing all subcategories for every Main category. How can I do?
index.html
{% for mainCatList in main_cat_list %}
<li class="subMenu"><a>{{ mainCatList.main_category_name }}</a>
<ul>
{% for subCat in cat_list %}
<li><i class="icon-chevron-right"></i>{{ subCat.category_name }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
views.html
from django.shortcuts import render
from .models import Product, Category, Main_Category
def homePageView(request):
main_cat_list = Main_Category.objects.all()
cat_list = Category.objects.all()
context = {'main_cat_list': main_cat_list, 'cat_list': cat_list}
return render(request, 'index.html', context)

I assume that your Category has foreign key to Main_Catagory. In that case, you can do this
{% for main_cat in main_cat_list %}
<li class="subMenu"><a>{{ main_cat.main_category_name }}</a>
<ul>
{% for sub_cat in main_cat.category_set.all %}
<li><i class="icon-chevron-right"></i>{{ sub_cat.category_name }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}

Related

Pagination in Django not working as expected

I wanted pagination for all the courses available and that was easy to achieve. But now I'm stuck because I wanted pagination for faculties also, which will show specific courses of the accessed faculty. I have 4 models: faculties, departments, studies, and courses. The pagination will show for faculties as well, but the problem is that if I try to go to the second page, it will redirect me to the second page of all courses list. Or, if I change page on all courses and then try to access a faculty, no course will show at all in the faculty.
def index(request):
course_list = Course.objects.all()
page = request.GET.get('page', 1)
paginator = Paginator(course_list, 1)
try:
courses = paginator.page(page)
except PageNotAnInteger:
courses = paginator.page(1)
except EmptyPage:
courses = paginator.page(paginator.num_pages)
faculty_list = Faculty.objects.all()
page = request.GET.get('page2', 1)
paginator = Paginator(faculty_list, 1)
try:
faculties = paginator.page(page)
except PageNotAnInteger:
faculties = paginator.page(1)
except EmptyPage:
faculties = paginator.page(paginator.num_pages)
context = {'courses': courses,
'faculties': faculties,
'departments': Department.objects.all(),
'studies': StudyProgramme.objects.all(),
'teachers': Teacher.objects.all()
}
return render(request, 'courses/index.html', context)
<div id="crs">
<h3>All courses</h3>
<ul>
{% for course in courses %}
<li><a href={{ course.slug }}>{{ course.name }}</a></li>
{% endfor %}
</ul>
<div class="pagination">
<span class="step-links">
{% if courses.has_previous %}
« first
{{ courses.previous_page_number }}
{% endif %}
<span class="current">
Page {{ courses.number }} of {{ courses.paginator.num_pages }}
</span>
{% if courses.has_next %}
{{ courses.next_page_number }}
last »
{% endif %}
</span>
</div>
</div>
{% for faculty in faculties %}
<div id="fac_{{ faculty.pk }}_tab" style="display:none;">
<h3> {{ faculty.name }} Courses</h3>
<ul>
{% for department in faculty.department_set.all %}
{% for study in studies %}
{% if study.department == department %}
{% for course in courses %}
{% if course.study_programme == study %}
<li>
<a class="first" href={{ course.slug }}>{{ course.name }}</a>
</li>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}
</ul>
<div class="pagination">
<span class="step-links">
{% if faculties.has_previous %}
« first
{{ faculties.previous_page_number }}
{% endif %}
<span class="current">
Page {{ faculties.number }} of {{ faculties.paginator.num_pages }}
</span>
{% if faculties.has_next %}
{{ faculties.next_page_number }}
last »
{% endif %}
</span>
</div>
</div>
{% endfor %}
It's not a Django problem that your view is most certainly handle one pagination parameter page which will direct to courses, so if you changed the get parameter for each of your model pagination it will work.
ex:
## views.py
page = request.GET.get('page')
## yourtemplate.html
yourtext
localhost:8000/MYVIEW/?page=2 # Goes to courses
## views.py
page = request.GET.get('faculties')
## yourtemplate.html
yourtext
##
localhost:8000/MYVIEW/?faculties=2 # Goes to faculties
etc..
edited:
{% for faculty in faculties %} change it to {% for faculty in faculties2 %} and remove faculties from your context, cuz you are repeating yourself as faculties2 and faculties hold the same queryset .
paginator = Paginator(course_list, 1)
paginator = Paginator(faculty_list, 1)
Changing your second instance name to paginator_two would solve your problem

Django list of item did not appear

I created model, view and template for display list of items in template but after I run the website It didn't anything. Please help me to solve this.
model.py
class waterLevel(models.Model):
height = models.CharField(max_length=250)
date = DateTimeField(max_length=250)
def __str__(self):
# #
return self.height + '-' + self.date
view.py
def compare(request):
all_waterLevels = waterLevel.objects.all()
context = {'all_waterLevels': all_waterLevels}
return render(request, 'Home/compare.html', context)
compare.html
{% if all_waterLevels %}
<ul>
{% for height in all_waterLevels %}
<li> {{ waterLevel.height }}</li>
<li> {{ waterLevel.date }}</li>
{% endfor %}
</ul>
{% else %}
<h3>no any details</h3>
{% endif %}
Try this :
{% if all_waterLevels %}
<ul>
{% for waterLevel in all_waterLevels %}
<li> {{ waterLevel.height }}</li>
<li> {{ waterLevel.date }}</li>
{% endfor %}
</ul>
{% else %}
<h3>no any details</h3>
{% 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

Paginating based on the alphabet (A-Z)

I have a simple contacts application where I want to paginate the contact list based on first name alphabet.
Here is my views.py
def contacts(request):
contact_list = Contact.objects.filter(user=request.user).order_by('first_name')
pages = [contact_list.filter(first_name__istartswith=i) for i in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"]
return render(request, 'contact/contact.html', {'contact_list': contact_list, 'pages': pages})
Here is my template
{% for alphabet in pages %}
{% if alphabet %}
<p>{{ alphabet }}</p>
{% for contact in contact_list %}
{% if contact in pages %}
<ul>
<li>{{ contact.first_name }}</li>
</ul>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
The output from this is something like
[<Contact: Steve>, <Contact: Su>]
Steve
Su
[<Contact: Ted>]
Ted
[<Contact: Zedd>]
Zedd
The {{ alphabet }} prints a list. What should I write to print the alphabet instead?
Capture the alphabet in the context variable:
pages = [{"letter": i, "contacts": contact_list.filter(first_name__istartswith=i) }
for i in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"]
return render(request, 'contact/contact.html', {'pages': pages}) # why pass contact_list?
Your template should be simplified to:
{% for alphabet in pages %}
{% if alphabet.contacts %}
<p>{{ alphabet.letter }}</p>
{% for contact in alphabet.contacts %}
<ul>
<li>{{ contact.first_name }}</li>
</ul>
{% endfor %}
{% endif %}
{% endfor %}

Iterate Items in Their Specific Groups in Django

In my Django template I want to be able to iterate through groups and items, but I want to iterate the items underneath their group. So far I have them iterating like this but it does not show which groups the items are a part of. How would I iterate the template to get this inclusion?
Views:
def manage(request):
group_list = Group.objects.order_by('name').filter(user=request.user)
item_list = Item.objects.order_by('name').filter(user=request.user)
return render(request, 'manage.html', {'group_list': group_list, 'item_list': item_list})
Template:
{% extends "base.html" %}
{% block content %}
{% for group in group_list %}
{{ group.name }}<br />
{% endfor %}
{% for item in item_list %}
{{ item.name }}<br />
{% endfor %}
{% endblock %}
UPDATE
Models (Sorry forgot to include this):
class Group(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=30)
class Item(models.Model):
user = models.ForeignKey(User)
group = models.ManyToManyField(Group)
name = models.CharField(max_length=30)
Your approach does unneccessary additional database hits. For performance reasons you should select just the items with related groups like this:
def manage(request):
item_list = Item.objects.order_by(
'group__name', 'name').filter(
user=request.user).select_related('group')
return render(request, 'manage.html', {'item_list': item_list})
The template looks like this:
{% extends "base.html" %}
{% block content %}
{% for item in item_list %}
{% ifchanged item.group.name %}
{{ item.group.name }}<br />
{% endifchanged %}
{{ item.name }}<br />
{% endfor %}
{% endblock %}
That way you only have ONE database hit regardless of how many groups there are.
I guess you have a fk from item to group
class Item(models.Model):
group = models.ForeignKey(Group)
views:
def manage(request):
group_list = Group.objects.order_by('name').filter(user=request.user)
return render(request, 'manage.html', {'group_list': group_list})
template:
{% extends "base.html" %}
{% block content %}
{% for group in group_list %}
{{ group.name }}<br />
<p>Item for this group</p>
{% for item in group.item_set.all %}
{{item.name}}
{% endfor %}
{% endfor %}
{% endblock %}

Categories

Resources