pythoncssdjangodjango-templatesdjango-messages

BUG: When passing django.messages variable through HTML tag


messages.info(request, 'Attendance Ready To Be Taken!')

Over here i use django messages to send a string to the user

{% for message in messages %} 
{% if message == 'Attendance Ready To Be Taken!' %}
  <div class="alert success"> 
    <span class="closebtn">&times;</span>   
      <strong>SUCCESS!</strong> {{message}} 
  </div> 

{% else %}
<div class="alert"> 
    <span class="closebtn">&times;</span>   
      <strong>WARNING!</strong> {{message}} 
</div>
{% endif %}
{% endfor %}

However, although the string is clearly the same..it doesn’t output SUCCESS message.

It can display the message indeed..but I want to filter if it’s a success message to be green..and error message to be red..just for user interface to warn users

.alert { 
     padding: 20px; 
     background-color: #f44336; 
     color: white; 
     opacity: 1; 
     transition: opacity 0.6s; 
     margin-bottom: 15px; 
} 
  
.alert.success {background-color: #04AA6D;}

Above is the CSS code for the two messages' styles for your reference.

The message “Attendance ready to be taken” should be showing green..but it’s red color in the webpage.

So I guess it didn’t fulfill the conditional 'if' statement. That’s why it goes to 'else', and becomes red color.

But I'm not sure why it doesn’t. Because the message displayed is the same thing as the string i compared it with..

Does anyone know what's causing this weird bug?


Solution

  • You have sent the info message, so its tag is info.

    The best to apply CSS classes dynamically is to make use of Message tags.

    Then define the tags of messages in the view as:

    messages.info(request, 'Attendance Ready To Be Taken!', extra_tags='success')
    

    Then this success tag will also become class in the element dynamically.

    Use in the template as:

    {% if messages %}
        {% for message in messages %}
            <div  class="alert {% if message.tags %} {{message.tags}} {% endif %}"> 
                <span class="closebtn">&times;</span>   
                <strong>SUCCESS!</strong> {{message}} 
            </div> 
        {% endfor %}
    {% endif %}
    

    To send error message which has error tag by default:

    messages.error(request, 'Attendance Not completed !', extra_tags='red')
    

    Then the red tag will also become class.

    The template can be same just need to add this css:

    .red {
      background-color: red;
    }
    

    This way it works dynamically.



    Another possible solution:

    You can use MESSAGE_LEVEL, they allow us to group by type so that they can be filtered or displayed differently in views and templates. Level is an integer describing the type of the message.

    Level      Value
    DEBUG       10
    INFO        20
    SUCCESS     25
    WARNING     30
    ERROR       40
    

    Then with your current code simply check the message in template using {% if message.level == 20 %}, so:

    {% for message in messages %} 
        {% if message.level == 20 %}
            <div class="alert success"> 
                <span class="closebtn">&times;</span>   
                <strong>SUCCESS!</strong> {{message}} 
                </div> 
    
                {% else %}
                <div class="alert"> 
                <span class="closebtn">&times;</span>   
                <strong>WARNING!</strong> {{message}} 
            </div>
        {% endif %}
    {% endfor %}