Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - How to show messages under ajax function

I am using AjaxForm plugin to submit my form without refresh. like:

$('#my_form_id').ajaxForm(function(){

        //something on success or fail
    });

this works correctly. when i click submit button it saves form datas without refresh. But before this ; i had django messages on my template file like:

{% for message in messages %}
    <div id="notice" align="center">
        {{ message }}
    </div>
{% endfor %}

what this code does is displaying notifications if post saved correctly or something failed.

now; i can't do that. i dont understand how i can use these messages tags with ajax functions.

it just saves the post. no notifications.

thank you.

edit :

add_post url : url(r'^admin/post/add/$', view='add_post',name='add_post'),

related view :

@login_required(login_url='/login/')
def add_post(request):
    template_name = 'add.html'
    owner = request.user
    if request.method == "POST":
        form = addForm(request.POST)
        if form.is_valid():
            titleform = form.cleaned_data['title']
            bodyform = form.cleaned_data['body']
            checkform = form.cleaned_data['isdraft']

            n = Post(title=titleform, body=bodyform, isdraft=checkform, owner=owner)
            n.save()
            messages.add_message(request, messages.SUCCESS,
                'New post created successfully!')
        else:
            messages.add_message(request, messages.WARNING,
                'Please fill in all fields!')
    else:
        form = addForm()
    return render_to_response(template_name, {'form': form, 'owner': owner,},
        context_instance=RequestContext(request))
like image 725
alioguzhan Avatar asked Nov 06 '12 18:11

alioguzhan


People also ask

Can you use AJAX with Django?

AJAX is the best way to perform asynchronous tasks in Django, at least on a small scale. If you want to do an asynchronous task on a bigger scale, you could do socket programming in Django or use front-end JavaScript libraries such as Angular, Vue, or React.

How send data from AJAX to Django?

To send and receive data to and from a web server, AJAX uses the following steps: Create an XMLHttpRequest object. Use the XMLHttpRequest object to exchange data asynchronously between the client and the server. Use JavaScript and the DOM to process the data.

What is textStatus in AJAX?

The textStatus is the textual status message returned by the server. The errorThrown parameter is the error thrown by jQuery. The callback function passed to the always() function is called whenever the AJAX request finishes, regardless of whether or not the AJAX request succeeds or fails.

How do you make a dynamic dropdown list with AJAX in Django?

To make an Ajax request, we first need to include the jquery library to our page. We define id = "question-subject" to our subject dropdown list. We select this list with the jquery selector and detect a change in this list with the change event. We assign the ID of the selected subject to a variable.


2 Answers

These are the tools/methods that helped me to solve the problem. First, I have a helper utility method called render_to_json:

# `data` is a python dictionary
def render_to_json(request, data):
    return HttpResponse(
        json.dumps(data, ensure_ascii=False),
        mimetype=request.is_ajax() and "application/json" or "text/html"
    )

I have a messages.html template to render the necessary html for the popup message(s):

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

When create a message in response to an AJAX request, I use Django's render_to_string to package the message(s) into a string that gets stored in a data dictionary, which then uses my render_to_json to return an appropriate response:

def my_custom_view(request)
    # ...  your view code
    data = {
        'msg': render_to_string('messages.html', {}, RequestContext(request)),
    }
    return render_to_json(request, data)

Then, in my jQuery $.post(...) callback function, I check to see if the response object has a msg attribute, and then insert the contents of response.msg into the DOM where I want it needs to be, with jQuery transitions if desired. My base.html template contains the <ul> container for the messages:

<ul id="popup-messages-content">
    {% include 'messages.html' %}
</ul>

Note that the above includes the messages.html for the case when you want to display messages on an actual page load (non-AJAX request) - it is blank if there are no messages, but the <ul> is still available to push AJAX-received messages into.

The last piece is the Javascript function (requires jQuery) I use in any $.post(...) callbacks to show the messages:

function showPopupMessage(content) {
    var elMessages = $('#popup-messages-content');
    if (elMessages.length && content) {
        elMessages.html(content);
    }
}
like image 157
James Addison Avatar answered Sep 17 '22 19:09

James Addison


You just create your messages as always and before sending the response you put them into a list of dicts:

django_messages = []

for message in messages.get_messages(request):
    django_messages.append({
        "level": message.level,
        "message": message.message,
        "extra_tags": message.tags,
})

Then you add any data and your messages and serialize it, e.g.:

data = {}
data['success'] = success
data['messages'] = django_messages

return HttpResponse(simplejson.dumps(data), content_type="application/json")

Finally at your ajax:

success: function(data){
                                success = data.success;
                                update_messages(data.messages);
                                if (success){
                                    ...                                                                             
                                }
                            },

And the update_messages function:

function update_messages(messages){
$("#div_messages").html("");
$.each(messages, function (i, m) {
                $("#div_messages").append("<div class='alert alert-"+m.level+"''>"+m.message+"</div>");
            });
    

}

It works perfectly and I found it very easily to implement

like image 32
steven2308 Avatar answered Sep 20 '22 19:09

steven2308