Home > OS >  sorting messages with tag in django template
sorting messages with tag in django template

Time:03-27

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 >&times;</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 >&times;</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 >&times;</span></div>
            </li>
        {% endfor %}
    </ul>
</div>

<div >
    <ul >
        {% for message in spreadsheet %}
            <li >
                <div class='message-content'>
                    <p>{{ message|safe }}</p>
                    <span >&times;</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
...
        
  • Related