F
F
filmincer2016-05-28 18:03:53
Django
filmincer, 2016-05-28 18:03:53

How to curb Django messages?

Hi all!
I have a long standing issue with the output in the django messages template. I personally need them in one case, just on one page. Therefore, in the view, I set a message and a redirect:

if not available_cars:
        carstoshow = None
        messages.error(request, 'Ваш диапазон дат занят для данного объекта.')
        return redirect('car_detail', pk=car_used_id)

I show the message in the template in the standard way:
{% if messages %}
<div class="alert alert-warning">
<div class="container text-center">
    {% for message in messages %}
    <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
    {% endfor %}
</div>
</div>
{% endif %}

Everything worked great. But after trying several times to login/logout, on that page I get a bunch of messages related to django-allauth authentication (the same in the admin panel):
6f15480572a74ba0882ca412e77eedad.png6ab10c5c1e1445d69e2a02bc37184dc2.png
I tried to set my message as messages.error, messages.info and so on. To filter out unnecessary ones in a template:
{% if messages.тип_моих_сообщений %}
{% for message in messages.тип_моих_сообщений %}

nothing comes out: either the whole heap or nothing.
Q: How can only my messages be allowed.
Thanks, any help would be appreciated

Answer the question

In order to leave comments, you need to log in

1 answer(s)
O
Oscar Django, 2016-05-29
@filmincer

Let's see how framework messages work.
https://github.com/django/django/blob/master/djang...

def messages(request):
    return {
        'messages': get_messages(request),
        'DEFAULT_MESSAGE_LEVELS': DEFAULT_LEVELS,
    }
...
def get_messages(request):
    if hasattr(request, '_messages'):
        return request._messages
    else:
        return []

This is how messages get on the page. Those. they are taken from request._messages. How do they get there?
https://github.com/django/django/blob/master/djang...
class MessageMiddleware(MiddlewareMixin):
    def process_request(self, request):
        request._messages = default_storage(request)
...
def default_storage(request):
    return import_string(settings.MESSAGE_STORAGE)(request)
...
MESSAGE_STORAGE = 'django.contrib.messages.storage.fallback.FallbackStorage'

So in request._messages we have FallbackStorage(request)
Let's move on to our code
What's going on here? Let's see:
https://github.com/django/django/blob/master/djang...
def error(request, message, extra_tags='', fail_silently=False):
    add_message(request, constants.ERROR, message, extra_tags=extra_tags,
                fail_silently=fail_silently)
...
def add_message(request, level, message, extra_tags='', fail_silently=False):
    if not isinstance(request, HttpRequest):
        raise TypeError("add_message() argument must be an HttpRequest object, "
                        "not '%s'." % request.__class__.__name__)
    if hasattr(request, '_messages'):
        return request._messages.add(level, message, extra_tags)  # *** THIS ***
    if not fail_silently:
        raise MessageFailure('You cannot add messages without installing '
                    'django.contrib.messages.middleware.MessageMiddleware')

Yup, the add method of the familiar FallbackStorage object is called.
It is passed as parameters:
- level = constants.ERROR = 40
- message = 'Your date range is busy for this object.'
- extra_tags = ''
Let's look at this method
https://github.com/django/django/blob/master/djang...
def add(self, level, message, extra_tags=''):
        if not message:
            return
        level = int(level)
        if level < self.level:
            return
        # Add the message.
        self.added_new = True
        message = Message(level, message, extra_tags=extra_tags)
        self._queued_messages.append(message)
...
def _get_level(self):
        if not hasattr(self, '_level'):
            self._level = getattr(settings, 'MESSAGE_LEVEL', constants.INFO)
        return self._level

From this code, we can conclude that a message enters the message queue if its level is greater than or equal to the one specified in settings.MESSAGE_LEVEL (default = contants.INFO = 20)
Thus, in order to add only our messages, you need to:
1) in settings.py install
# settings.py
...
MY_SUPER_ERROR = 80
MESSAGE_LEVEL = MY_SUPER_ERROR
...

2) Write in view
if not available_cars:
        carstoshow = None
        messages.add_message(request, settings.MY_SUPER_ERROR, 'Ваш диапазон дат занят для данного объекта.')
        return redirect('car_detail', pk=car_used_id)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question