D Dhaliwal
D Dhaliwal

Reputation: 552

Django: load contents of "base" template with ajax

I want to load notifications in my base template after click on the notification icon. Currently I am fetching the notifications with the help of custom context processor.

contex_processors.py:

def notifications(request):
if request.POST and request.is_ajax:
    notify_obj = #some logic here
    return {'notify_obj': notify_obj}

But after clicking on the button whole page gets refreshed. I want to implement ajax to the base template so only notifications division gets refreshed.

I know how to implement ajax in other templates but not sure how to implement in base template.

Please help me on this, or tell me if I need to follow some other approach for this.

Edit: Adding base.html for more clarification.

<div id="notify-div">
<form id="notify-form" method="post">
    <input type="submit" name="notify" value="Show notifications">
    {% csrf_token %}
</form>
{% for notify in notify_obj %}
    {{ notify.user.user_id.username }}, {{ notify.wish.wish_text }} - {{ notify.added }}
{% endfor %}
</div>
<script>
    $(document).ready(function() {
        $('#notify_form').submit(function() { // catch the form's submit event
            $.ajax({ // create an AJAX call...
                data: $(this).serialize(), // get the form data
                type: $(this).attr('method'), // GET or POST
                url: $(this).attr('action'), // the file to call
                success: function(response) { // on success..
                    $('#notify_div').html(response); // update the DIV
                }
            });
            return false;
        });
    });
</script>`

Please mention what JS should i use here to make it an ajax call.

Upvotes: 0

Views: 500

Answers (1)

Moses Koledoye
Moses Koledoye

Reputation: 78546

Had the same problem of late. Updating the base template via Ajax might require a little tweak on your all your view functions, viz:

if request.is_ajax:
    #obj is your desired dict response obj
    return JsonResponse(obj)

but this would be an overkill. To avoid the ambiguity, simply add a decorator to all your view functions:

@ajax_processor(context_processor=your_context_processor)

and implement decorator like so:

def ajax_processor(context_processor):    
    def decorator(func):
        '''Process all AJAX requests with context_processors'''
        @wraps(func)
        def wrapper(request, *args, **kwargs):
            if request.is_ajax():
                return context_processor(request)
            else:
                #Decorator does nothing
                return func(request, *args, **kwargs)
        return wrapper
    return decorator

This would mean all your Ajax request need to go through this context_processor, which is not a bad idea. But if you wish otherwise, you can throttle the "if" statement to only pass the exact Ajax request you want the decorator to serve.

Upvotes: 1

Related Questions