How can I print the 'date received' only one time while using a for loop?

假如想象 提交于 2019-12-23 04:06:12

问题


I am trying to group messages by received today, received yesterday, ect. To clarify, I am trying to have a single header that says "Today" and then list those messages underneath. I am NOT trying to print "Today" along with each message that was received on that day (which is currently what's happening).

I currently have the TODAY and YESTERDAY headers inside of my for loop so I understand that is why it is printing these headers for each mail message, but as previously stated I just want to print them one time. My question is, how can I achieve this using the code below? Do I need to make separate for loops for each time period (today, yesterday, last week, ect.), or is there a more efficient way to do this?

{% for message in messages %}
    {% if message.date - current.date < 24 hours %}
        TODAY
        Sent by: {{ message.sender }}
        {{ message.body }}
    {% elif message.date - current.date > 24 hours and message.date - current.date < 48 hours %}
        YESTERDAY
        Sent by: {{ message.sender }}
        {{ message.body }
    {% endif %}
{% endfor %}

回答1:


You can use {{forloop.first}} for this. So your code can be updated to

{% for message in messages %}
    {% if message.date - current.date < 24 hours %}
        {% if forloop.first %}
            TODAY
        {% endif %}
    {% elif message.date - current.date > 24 hours and message.date - current.date < 48 hours %}
       {% if forloop.first %}
        YESTERDAY
       {% endif %}
    {% endif %}

    Sent by: {{ message.sender }}
    {{ message.body }}

{% endfor %}



回答2:


I am trying to group messages by received today, received yesterday

@Rohan gave you an answer but it will run the check on each loop even though you only print out the string once.

A better approach would be to organize your messages and order them by the date difference.

The best way to do this is to group the messages in the view before sending them to the template, like this:

from collections import defaultdict
from django.utils.timesince import timesince  # This will give us nice human
                                              # friendly date offsets

def some_view(request):

   messages = Message.objects.order_by('date')
   grouped_messaged = defaultdict(list)
   for message in messages:
      grouped_messages[timesince(message.date)].append(message)

   return render(request, 'template.html', {'all_messages': messages})

Now your template is a lot simpler:

<ul>
{% for header,messages in all_messages.items %}
    <li>{{ header }}
    <ul>
    {% for message in messages %}
        <li>{{ message.sender }} - {{ message.body }}</li>
    {% endfor %}
    </ul></li>
{% endfor %}
</ul>


来源:https://stackoverflow.com/questions/27539281/how-can-i-print-the-date-received-only-one-time-while-using-a-for-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!