Home > front end >  How to list objects of the same date?
How to list objects of the same date?

Time:01-08

I want to list all items in my template, but I want to list items under the same year. For example, under the 2021 title, model objects for that year should be listed. Year titles should come dynamically. How can I do it?

views.py

def press_list(request):
    press_contents = PressContent.objects.all().order_by('-date')
    context = {
        'press_contents': press_contents
    }
    return render(request, "press_list.html", context)

models.py

class PressContent(models.Model):
    label = models.CharField(max_length=500)
    url = models.URLField(max_length=500)
    date = models.DateTimeField(blank=True, null=True)
    

press_list.html

{% for press in press_contents %}
        <div  style="width: 18rem; margin:15px">
            <div >
                {{ press.date.year }}
            </div>
            <ul >
                <li ><a href="{{ press.url }}">{{ press.label }}</a></li>
                # Other objects from this year should come here.
            </ul>
        </div>
{% endfor %}

To be clear: 2021

  • obj 1
  • obj 2 2020
  • obj 3
  • obj 4 ... ...

CodePudding user response:

You can work with the {% regroup … by … %} template tag [Django-doc]:

{% regroup press_contents by year as pressitems %}
{% for pressyear in pressitems %}
    <div  style="width: 18rem; margin:15px">
    <div >
                {{ pressyear.grouper }}
            </div>
            <ul >
                {% for press in pressyear.list %}
                    <li ><a href="{{ press.url }}">{{ press.label }}</a></li>
                # Other objects from this year should come here.
                {% endfor %}
            </ul>
        </div>
{% endfor %}

CodePudding user response:

If you can afford to convert a queryset into a list of objects, then you can use the built-in template filter regroup (I think, I've never used it).

Another approach would be to write a python generator function and pass it in the context, to be iterated over by the template. This avoids issues with resource consumption when the queryset comprises a large number of objects. Something like

def year_grouper():
    qs = PressContent.objects.all().order_by('-date')
    last_object_year = 1000000000
    for obj in qs:
        obj.year_changed = ( obj.date.year != last_object_year )
        yield obj
        last_object_year = obj.date.year

and

{% for obj in year_grouper %}
    {% if obj.year_changed %}
       ... year header, etc.
    {% endif %}
    ... display obj
{% endfor %}
  •  Tags:  
  • Related