1

I have a little problem with annotate. I want to display records from my class Kategorie in the main html file. I used the annotate method to take the query from db. I used in the second class Firmy the ForeignKey to class Kategorie. Now I dont know how to display for example how many websites added in the class Firmy are in the for example in category Business. Now I have something like: "Business (2)(3)(4)" when I used annotate with count by id. This is my models.py

from django.db import models
from django.utils import timezone


class Kategorie(models.Model):
    glowna = models.CharField(max_length=150, verbose_name='Kategoria')

    class Meta:
        verbose_name='Kategoria'
        verbose_name_plural='Kategorie'

    def __str__(self):
        return self.glowna


class Witryna(models.Model):
    nazwa = models.CharField(default="", max_length=150, verbose_name = 'Nazwa strony')
    adres_www = models.CharField(max_length=70, verbose_name='Adres www')
    slug = models.SlugField(max_length=250, verbose_name='Przyjazny adres url')
    email = models.CharField(max_length=100, verbose_name='Adres e-mail')
    text = models.TextField(max_length=3000, verbose_name='Opis strony')
    kategoria = models.ForeignKey(Kategorie, verbose_name='Kategoria')
    data_publikacji = models.DateTimeField(blank=True, null=True, verbose_name='Data publikacji')

    class Meta:
        verbose_name='Strona www'
        verbose_name_plural = 'Strony www'

    def publikacja(self):
        self.data_publikacji=timezone.now()
        self.save()

    def __str__(self):
        return self.nazwa

And some part from views.py

from django.db.models import Count

    wpisy_kat = Kategorie.objects.annotate(cnt_witryna=Count('Witryna'))

So what kind of method or tags I have to use to display for example:

Business(34)
Industry(21)
Health Care(11)

where the name od category is field from class Kategorie and integer is a result from query to database how many websites are in for example Business category?

My html file is:

{%  for kategoria in kategorie %}
<table>
<tr>
<td>

<li><a href="{% url 'detale_kat' slug_kat=kategoria.slug_kat %}">{{ kategoria.glowna|linebreaksbr }} </a></li>
{% for wpis in wpisy_kat %}
{{ wpis }} ({{ cat.cnt_witryna }})
{% endfor %}
</td>
</tr>
</table>
{%  endfor %}

and the main html file:

{% include 'firmy/header.html' %}
<html>
<body>
<p>
<center>
<ul id="menu">
    <li><a href="link1.html">Strona główna</a></li>
    <li><a href="link2.html">Jak dodać stronę</a></li>
    <li><a href="link3.html">Regulamin</a></li>
    <li><a href="link4.html">Kontakt</a></li>
</ul>
</center>
<div class="glowna">
    <div class="lewe_menu">

    <h3><center>Ostatnio dodane</center></h3>

    {%include 'firmy/widok_strony.html'%}
    </div>
    <div class="srodek">

        <h3><center>Kategorie</center></h3>
        <center>{%include 'firmy/widok_kategorii.html'%} </center>
    </div>
    <div class="prawe_menu">

    <h3><center>Reklama</center></h3>
    <center>Tutaj wpisz kod reklamy </center>
    </div>
    {% include 'firmy/footer.html' %}
</div>
</body>

</html>

view.py file

from django.shortcuts import render, get_object_or_404
from .models import Witryna, Kategorie
from django.utils import timezone
from django.db.models import Count


def widok_strony(request):
    firmy = Witryna.objects.filter(data_publikacji__lte=timezone.now()).order_by('data_publikacji')
    return render(request, 'firmy/widok_strony.html', {'firmy': firmy})

def widok_kategorii(request):
    kategorie = Kategorie.objects.all()
    wpisy_kat = Witryna.objects.annotate(cnt_kategoria=Count('kategoria'))
    return render(request, 'firmy/widok_kategorii.html', {'kategorie': kategorie, 'wpisy_kat': wpisy_kat,})

def index(request):
    firmy = Witryna.objects.filter(data_publikacji__lte=timezone.now()).order_by('data_publikacji')
    kategorie = Kategorie.objects.order_by('glowna')
    wpisy_kat = Witryna.objects.annotate(cnt_witryna=Count('kategoria'))
    return render(request, 'firmy/index.html', {'kategorie': kategorie, 'wpisy_kat': wpisy_kat, 'firmy': firmy})

def detale_strony(request, slug):
    det_wpisu = get_object_or_404(Witryna, slug=slug)
    firmy = Witryna.objects.filter(data_publikacji__lte=timezone.now()).order_by('data_publikacji')
    return render(request, 'firmy/detale_strony.html', {'det_wpisu': det_wpisu, 'firmy': firmy})

def detale_kat(request, slug_kat):
    det_kategorii = get_object_or_404(Kategorie, slug_kat=slug_kat)
    firmy = Witryna.objects.filter(data_publikacji__lte=timezone.now()).order_by('data_publikacji')
    return render(request, 'firmy/detale_kat.html', {'det_kategorii': det_kategorii, 'firmy': firmy})
8
  • please update your question with the html template you are using (you can delete the screenshot, it's not helping in this case) Commented Aug 12, 2017 at 10:15
  • the html files were attached Commented Aug 12, 2017 at 10:21
  • be careful, in {{ wpis }} ({{ cat.cnt_witryna }}) : replace cat by wpis, then you are mixing two for loops, the annotate method already gives you the list of categories, you should try with only mine to check, and then add the <a> tag with wpis.slug_kat (no need to use a table) Commented Aug 12, 2017 at 10:43
  • Yop I changed on {{wpis.cnt.witryna}} and the result is for example: Aktualności i media (1)(1)(1). When I enter in to the category in every category i have this same pages not only for example: google.com in category Websites. Commented Aug 12, 2017 at 10:53
  • please add also the code of view that renders this html, i cannot understand why it's listing sites instead of categories Commented Aug 12, 2017 at 10:58

1 Answer 1

1

Your view needs to return something like :

wpisy_kat = Kategorie.objects.annotate(cnt_witryna=Count('witryna'))
return render(request, 'app/template.html', {'wpisy_kat': wpisy_kat})

template.html :

<ul>
{% for cat in wpisy_kat %}

    <li>{{ cat }} ({{ cat.cnt_witryna }})</li>

{% endfor %}
</ul>

EDIT :

You can add sorting or filtering to the annotate query, no need to pass 2 parameters from the view, and no need to perform to for/loops :

replace the query in the view :

wpisy_kat = Kategorie.objects.annotate(cnt_witryna=Count('witryna')).order_by('glowna')

Then in the HTML:

<ul>
{% for cat in wpisy_kat %}

    <li><a href="{% url 'detale_kat' slug_kat=cat.slug_kat %}">{{ cat }} ({{ cat.cnt_witryna }}) </a></li>

{% endfor %}
</ul>
Sign up to request clarification or add additional context in comments.

10 Comments

It's returned me all pages what I have in Database without splited on categories.
@killerbees Kategorie.objects.annotate(cnt_witryna=Count('witryna')) this line should list all the categories and adds the number of associated pages (witryna in lowercase), have you check this within the shell ?
I wrote the post aswer so my problem is above that comments
@killerbees ok, i saw the screenshot, the categories are in blue ? what are the names listed in black ? (you should better update your post than post an answer like this)
Yes categories what were added in Kategorie class are in blue colour. The black colored like:"Bardzo fajna strona internetowa" and the rests, are the titles from websites added in Witryna class. I want to build a app like Web directory for example: bazastron.com.pl when You visit that website, On this website You will see the central <div> with categories and numer of pages in category.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.