Skip to content

Latest commit

 

History

History
91 lines (70 loc) · 3.85 KB

dispatch-ajax-requests.rst

File metadata and controls

91 lines (70 loc) · 3.85 KB

Dispatching Ajax requests from an AngularJS controller

Wouldn't it be nice to call a Django view method, directly from your AngularJS controller, similar to Remote Procedure Calls?

This can simply be achieved by adding a djangular mixin class to that view:

from django.views.generic import View
from djangular.views.mixins import JSONResponseMixin, allowed_action

class MyJSONView(JSONResponseMixin, View):
    # other view methods

    @allowed_action
    def process_something(self, in_data):
        # process input data
        out_data = {
            'foo': 'bar',
            'success': True,
        }
        return out_data

Let's assume that the URL used for posting this request is attached to this view. Now in your AngularJS controller, calling the view's method process_something is as simple as:

function MyFormCtrl($scope, $http) {
    $scope.submit = function() {
        var in_data = {action: 'process_something'};
        angular.copy($scope.my_prefix, in_data);
        $http.post('/url/of/my_json_view', in_data)
            .success(function(out_data) {
                if (out_data.success) {
                    // update the controllers scope
                } else {
                    alert('Something went wrong');
                }
            });
    }
}

Note

In real code you should not hard code the URL into an AngularJS controller as shown in this example. Instead, inject an object containing the URL into your controller as explained in :ref:`manage Django URL's for AngularJS <manage-urls>`.

The special keyword action, as declared in the post data to be sent, contains the method name of the view to be called. In MyJSONView.process_something() this action tuple is then already stripped off from the passed in_data and the method receives a Python dictionary containing an exact copy of the Javascript object $scope.my_prefix.

Warning

To eschew the possibility for an attacker to call any method of your view by setting the keyword action to an arbitrary method name, the author of the view must explicitly give permission to call this method. This is done by adding the decorator @allowed_action in front of the methods to be exposed. Otherwise the remote caller receives an HttpResponseBadRequest error.

Dispatching Ajax requests using method GET

Sometimes you only have to fetch some data from the server. If you prefer to fetch this data using the GET method, you have no way to pass in the action keyword with the remote method you want to execute. But django-angular lets you hard-code that action inside your URL dispatcher:

urlpatterns = patterns('',
    ...
    url(r'^fetch-some-data.json$', MyResponseView.as_view(), {'action': 'get_data'}),
    ...
)

By calling the URL fetch-some-data.json, the responding view dispatches incoming requests directly onto the method get_data. This works with GET requests as well as with POST requests:

class MyResponseView(JSONResponseMixin, View):
      def fetch_data(self):
          return { 'foo': 'bar' }

Note

Here for GET requests, the method fetch_data does not require the decorator @allowed_action, since this method invocation has been determined by programmer, rather than the client. Therefore there is no security issue here.