# Passing a dictionary to Django's messages framework

In order to display some 'flash' message after a form submission like a success message or an error message we make use of [messages framework](https://docs.djangoproject.com/en/4.1/ref/contrib/messages/) which is built-in in Django.

I was doing a `return redirect('dashboard')` from a job posting form. Thing is, I am redirecting to the dashboard from many such forms which are located in different pages. I wasn't redirecting to a dedicated page unique to each form submission like job post, contact etc - as a result, I don't know details such as, from which page its come from, or other success form submission data, specific to the page, that are required to be shown on the dashboard.

In views.py :
```
from django.contrib import messages
```

In `class AddJob(LoginRequiredMixin, generic.CreateView):` of views.py :
```
def form_valid(self, form):
    form.instance.user = self.request.user
    super(AddJob, self).form_valid(form)
    
    data = {
        "section": "job",
        "message": "You've successfully posted a job - thank you - it'll be available post approval",
        "some_other_data_1": "foo",
        "some_other_data_2": "bar"
    }
    
    messages.add_message(self.request, messages.SUCCESS, data, extra_tags="dictionary")

    return redirect('dashboard')
```

An example of sending in a message is as follows :
```
messages.add_message(request, messages.INFO, 'Hello world.')
```

The actual message, `'Hello world.'` is a string.

There's one slight problem using this method of sending in `data` which is a dictionary - it'll be converted to a string and the resultant message argument would be 
```
'{"section": "job", "message": "You\'ve successfully posted a job - thank you - it\'ll be available post approval", "some_other_data_1": "foo", "some_other_data_2": "bar" }'
```
which is not a dictionary but rather a string containing the dict.

I searched for a lot of workarounds to pass in an actual dict to `add_message` but in vain.

`{{ message }}` below will output the string representation of the python dictionary `data`.

```
{% if messages %}
<ul class="messages">
    {% for message in messages %}
    <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>
        {{ message }}
    </li>
    {% endfor %}
</ul>
{% endif %}
```

So we won't be able to do things like `{{ message.section }}` or `{{ message.message }}` or `{{ message.some_other_data_1 }}`

**Enter JavaScript :**

Load [AlpineJS](https://alpinejs.dev) in your base HTML template : (this is only to make life simpler instead of doing something like `divElement.innerHTML = data.message` etc or using jQuery)
```
<script src="https://unpkg.com/alpinejs@3.10.3/dist/cdn.min.js" defer></script>
```

Now in &lt;app&gt;/templates/dashboard.html, `message.tags` will be 'dictionary success' since we passed in `extra_tags="dictionary"` to `messages.add_message` before.
```
<div>
    {% if messages %}
        {% for message in messages %}
            {% if 'dictionary' in message.tags %}
                <script>
                    let data = {{ message | safe }};
                    console.log(data);
                </script>
                <div x-data="{ message_data : data }">
                    <h3>Message :</h3>
                    <p x-text="message_data.section"></p>
                    <p x-text="message_data.message"></p>
                    <p x-text="message_data.some_other_data_1"></p>
                </div>
            {% else %}
                <div>{{ message }}</div>
            {% endif %}
        {% endfor %}
    {% endif %}
</div>
```
`x-text="message_data.section"` will have the element's (in this case the `p` tag) content to have the value of `message_data.section` which is `job`
