Login

Jquery ajax csrf framework for Django

Author:
chriszweber
Posted:
January 23, 2012
Language:
JavaScript
Version:
1.3
Tags:
json jquery csrf
Score:
1 (after 1 ratings)
  1. Framework to extend the jquery ajax() function to construct post requests that contain a csrf token.

  2. The example view used with the framework takes JSON data and returns JSON data containing either:

  3. "success" with a message and additional dictionary of JSON data to use in the page
  4. "error" with an error message.

  5. The ajax function framework satisfies Django's csrf requirements by injecting a csrf token into the post requests created using the function.

This example is a form with ~160 fields that we wanted to help fill in customer information to automatically.

  1. User calls the lookup() script from the onblur attribute of the customer_id form field by leaving the field.
  2. The lookup script takes the contents of the customer_id formfield and uses the jquery ajax() function to construct a JSON post request to the "/json /?act=" url.
  3. The json view takes actions as get requests. We pass the post request to the JSON url already including the get request. "/json/?act=lookup"
  4. The jquery framework in the snippet includes a csrf token in the ajax request automatically.
  5. The customer_id is passed as JSON to the json view lookup action and customer details are attempted to be looked up in the database.
  6. If successful the request returns a JSON dictionary of customer details which are pushed into the formfields using javascript in the lookup() function.

The end result is if the user fills out the customer_id field of the form first (which we suggest with tooltip overlay) the customer name and address information will populate automatically.

*Credit to Guangcong Luo https://github.com/Zarel

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
//javascript

// Django CSRF framework
$(document).ajaxSend(function(event, xhr, settings) {
    function getCookie(name) {
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    function sameOrigin(url) {
        // url could be relative or scheme relative or absolute
        var host = document.location.host; // host + port
        var protocol = document.location.protocol;
        var sr_origin = '//' + host;
        var origin = protocol + sr_origin;
        // Allow absolute or scheme relative URLs to same origin
        return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
            (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
            // or any other URL that isn't scheme relative or absolute i.e relative.
            !(/^(\/\/|http:|https:).*/.test(url));
    }
    function safeMethod(method) {
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }

    if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
        xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
    }
});


		function lookup()
		{
			var cust_id = $('#customer_id').val();
			
			$.ajax('/json/?act=lookup', {type: 'POST', data: {
				customer_id: cust_id
			}, dataType: 'json'})
			.done(function(data) {
				//alert(data);
				if (data.success) {
					$('input[name=customer_name]').val(data.customer_name);
					$('input[name=customer_address]').val(data.address);
					$('input[name=customer_city]').val(data.city);
					$('input[name=customer_state]').val(data.state);
					$('input[name=customer_zip]').val(data.zip);
					$('input[name=customer_contact_name]').val(data.contact_name);
				}
			})
			.fail(function() { console.log("lookup error"); });
		}
		
//template	
//When the user leaves the field containing a lookup value it is looked up in database and fills other form fields automatically

<div class="customer_information">
    <span>Customer Information</span>
    <div class="formrow"> 
        <div class="formbox"> 
            <label>Customer Name</label> 
            <input type="text" name="customer_name" maxlength="255" />
        </div> 
    </div> 
    <div class="formrow"> 
        <div class="formbox"> 
            <label>Address</label> 
            <input type="text" name="customer_address" maxlength="255" /> 
        </div> 
    </div> 
    <div class="formrow"> 
        <div class="formbox formboxcity"> 
            <label>City</label> 
            <input type="text" name="customer_city" maxlength="255" /> 
        </div> 
        <div class="formbox formboxstate"> 
            <label>State</label> 
            <input type="text" name="customer_state" maxlength="255" />
        </div> 
        <div class="formbox formboxzip"> 
            <label>ZIP</label> 
            <input type="text" name="customer_zip" maxlength="255" /> 
        </div>
    </div> 
    <div class="formrow">
        <div class="formbox formboxhalf">
            <label>Customer ID#</label>
            <input onblur="Lookup()" type="text" id="customer_id" name="customer_id" maxlength="255" />
        </div>
        <div class="formbox formboxhalf">
            <label>Contact Name</label>
            <input type="text" name="customer_contact_name" maxlength="255" />
        </div>
    </div>
</div>

//urls.py

(r'^json/$', json)

//views.py

from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.template.context import RequestContext

from myapp.models import customer

from django.core.serializers import serialize
from django.utils.simplejson import dumps, loads, JSONEncoder
from django.db.models.query import QuerySet

#extend simplejson to allow serializing django queryset objects directly
class DjangoJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, QuerySet):
            return loads(serialize('json', obj))
        return JSONEncoder.default(self, obj)

def json(request):

    if 'act' in request.GET:
        act = request.GET['act']

        if act == 'lookup':

            if 'customer_id' in request.POST:

                customer_id = request.POST['customer_id']
                customer_id = int(customer_id)
                
                try:
                    BP = customer.objects.get(cust_id_number=customer_id)
                    
                    success = 'record found'
            
                    cust_id_number = BP.cust_id_number
                    cust_customer_name = BP.cust_customer_name
                    cust_address = BP.cust_address
                    cust_city = BP.cust_city
                    cust_state = BP.cust_state
                    cust_zip = BP.cust_zip
                    cust_contact_name = BP.cust_contact_name
        
                    json_dict = {
                                 'success': success,
                                 'id_number': cust_id_number,
                                 'customer_name': cust_customer_name,
                                 'address': cust_address,
                                 'city': cust_city,
                                 'state': cust_state,
                                 'zip': cust_zip,
                                 'contact_name': cust_contact_name
                                 }
                    
                    json = dumps(json_dict, cls=DjangoJSONEncoder) #cls = helper
        
                    return HttpResponse(json)

More like this

  1. ajax_validator generic view by amitu 6 years, 6 months ago
  2. Django and jQuery -- pulling info from a long-running process by Donn 6 years, 8 months ago
  3. Ajax progress bar by ebartels 7 years, 1 month ago
  4. SignedForm: CSRF-protect forms with a hidden token field by exogen 6 years, 7 months ago
  5. testdata tag for templates by showell 6 years ago

Comments

Please login first before commenting.