I'm receiving a list of messages, each message has a tag. It may be "info", "warning", "danger" and "spreadsheet". I need to display the first three first and then spreadsheet's but in collapsible if there are more than 3 of them.
So for all messages BUT spreadsheet the template is:
<div >
<ul >
{% for message in messages %}
<li{% if message.tags %} {% else %} {% endif %}>
<div >
<p>{{ message|safe }}</p>
<span >×</span></div>
</li>
{% endfor %}
</ul>
</div>
For tags with "spreadsheet" tag the template is:
<div >
<ul >
{% for message in messages %}
<li >
<div class='message-content'>
<p>{{ message|safe }}</p>
<span >×</span>
</div>
</li>
{% endfor %}
{% if messages|length > 3 %}
<button id="show_more" >Show all</button>
{% endif %}
</ul>
</div>
Where button is shown for spreadsheet messages if there are more then 3 of them and shows all of them on click.
Problem is that I receive these messages in one array and I have no guarantee that they won't be all mixed up in different order.
I need to sort them somehow with message.tags
to two separate arrays? Or use some smart if but I cannot figure out how to achieve that in the template. Could you please help?
EDIT: After comment below I am trying to sort the messages in the view.py
m = messages.get_messages(request)
if len(m) > 0:
context['msgs'] = m.filter(tags__in=['info', 'warning', 'danger']).order_by('tags')
context['spreadsheet'] = m.filter(tags='spreadsheet')
m is FallbackStorage
object and it doesn't have filter
method. m.objects
and FallbackStorage.objects
do not work either (for the same reason: has no attribute 'objects'). I've tried to do all above with messages
straight away (without the get_messages
method) but the result is the same. How to filter this correctly?
CodePudding user response:
you can divide messages in two different querysets. On your views.py:
context['messages'] = messages.filter(tags__in = ['info','warning','danger']).order_by('tags')
context['spreadsheet'] = messages.filter(tags = 'spreadsheet')
On your template:
<div >
<ul >
{% for message in messages %}
<li{% if message.tags %} {% else %} {% endif %}>
<div >
<p>{{ message|safe }}</p>
<span >×</span></div>
</li>
{% endfor %}
</ul>
</div>
<div >
<ul >
{% for message in spreadsheet %}
<li >
<div class='message-content'>
<p>{{ message|safe }}</p>
<span >×</span>
</div>
</li>
{% endfor %}
{% if messages|length > 3 %}
<button id="show_more" >Show all</button>
{% endif %}
</ul>
</div>
EDIT:
According to you comment. I suggest to try something like this:
msgs = []
spreadsheet = []
m = messages.get_messages(request)
if len(m) > 0:
for mensaje in m:
#TRY THE THREE OPTIONS BECAUSE I DON'T KNOW THE MESSAGES' STRUCTURE#
if 'spreadsheet' in message['tags']:
#if 'spreadsheet' in message.tags:
#if 'spreadshhet' in message.tags():
spreadsheet.append(mensaje)
else:
msgs.append(mensaje)
context['msgs'] = msgs
context['spreadsheet'] = spreadsheet
CodePudding user response:
get_messages
is a utility function and not a class method. You can read more about how to use it in the docs here.
In your view you can do:
from django.contrib.messages import get_messages
...
message_list = get_messages(request)
messages = []
spreadsheet_messages = []
for message in message_list:
tags = message.tags
if ("info" in tags) or ("warning" in tags) or ("danger" in tags):
messages.append(message)
if "spreadsheet" in tags:
spreadsheet_messages.append(message)
context["messages"] = messages
context["spreadsheet"] = spreadsheet_messages
...