Perform basic CRUD operations¶
When using Angular’s $resource to build services, each service comes with free CRUD (create, read, update, delete) methods:
{ 'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'}
};
Of course this need support on the server side. This can easily be done with django-angular‘s
NgCRUDView
.
Note
remove()
and delete()
do exactly the same thing. Usage of remove()
is
encouraged, since delete
is a reserved word in IE.
Configuration¶
Subclass NgCRUDView
and override model attribute:
from djng.views.crud import NgCRUDView
class MyCRUDView(NgCRUDView):
model = MyModel
Add urlconf entry pointing to the view:
...
url(r'^crud/mymodel/?$', MyCRUDView.as_view(), name='my_crud_view'),
...
Set up Angular service using $resource
:
var myServices = angular.module('myServices', ['ngResource']);
myServices.factory('MyModel', ['$resource', function($resource) {
return $resource('/crud/mymodel/', {'pk': '@pk'}, {
});
}]);
Note
Since there is a known bug with $resource not respecting trailing slash, the urls in Django urlconf used by $resource
must either not have trailing slash or it should be optional (preferred) - e.g. url/?
. Adding the trailing slash
to the $resource configuration regardless (/crud/mymodel/
) ensures future compatibility in case the bug gets fixed and
will then follow Django’s trailing slash convention. This has been fixed in AngularJS 1.3. More information here trailingSlashBugFix
Another quick change is required to Angular app config, without this DELETE
requests fail CSRF
test:
var my_app = angular.module('myApp', [/* other dependencies */, 'ngCookies']).run(
function($http, $cookies) {
$http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;
// Add the following two lines
$http.defaults.xsrfCookieName = 'csrftoken';
$http.defaults.xsrfHeaderName = 'X-CSRFToken';
});
That’s it. Now you can use CRUD methods.
Optional attributes¶
The following options are currently available to subclasses of NgCRUDView
:
fields
¶
Set this to a tuple or list of field names for only retrieving a subset of model fields during a
get or query operation. Alternatively, if this may vary (e.g. based on query parameters or
between get and query) override the get_fields()
method instead.
With None
(default), all model fields are returned. The object identifier (pk
) is always
provided, regardless of the selection.
form_class
¶
Set this to a specific form for your model to perform custom validation with it.
Alternatively, if it may vary you can override the get_form_class()
method instead.
With None
(default), a modelForm including all fields will be generated and used.
slug_field
¶
Similar to Django’s SingleObjectMixin, objects can be selected using an alternative key such as a title or a user name. Especially when using the ngRoute module of AngularJS, this makes construction of descriptive URLs easier. Query parameters can be extracted directly from $route or $routeParams and passed to the query.
This attribute (default is 'slug'
) describes the field name in the model as well as the query
parameter from the client. For example, if it is set to 'name'
, perform a query using
var model = MyModel.get({name: "My name"});
Note
Although the view will not enforce it, it is strongly recommended that you only use unique
fields for this purpose. Otherwise this can lead to a MultipleObjectsReturned
exception, which is not handled by this implementation.
Also note that you still need to pass the object identifier pk
on update and delete
operations. Whereas for save operations, the check on pk
makes the distinction between
an update and a create operation, this restriction on deletes is only for safety purposes.
allowed_methods
¶
By default, NgCRUDView
maps the request to the corresponding django-angular method, e.g. a DELETE
request would call
the ng_delete
method.
allowed_methods
is set by default to ['GET', 'POST', 'DELETE']
.
If you need to prevent any method, you can overrride the allowed_methods
attributes. Alternatively, you can use the exclude_methods
attributes.
exclude_methods
¶
To allow all methods by default, exclude_methods
is set as an empty list.
To exclude any method, you can override this attribute to exclude the 'GET'
, 'POST'
or 'DELETE'
.
See allowed_methods
for more informations.
Usage example¶
myControllers.controller('myCtrl', ['$scope', 'MyModel', function ($scope, MyModel) {
// Query returns an array of objects, MyModel.objects.all() by default
$scope.models = MyModel.query();
// Getting a single object
var model = MyModel.get({pk: 1});
// We can crete new objects
var new_model = new MyModel({name: 'New name'});
new_model.$save(function(){
$scope.models.push(new_model);
});
// In callback we push our new object to the models array
// Updating objects
new_model.name = 'Test name';
new_model.$save();
// Deleting objects
new_model.$remove();
// This deletes the object on server, but it still exists in the models array
// To delete it in frontend we have to remove it from the models array
}]);
Note
In real world applications you might want to restrict access to certain methods.
This can be done using decorators, such as @login_required
.
For additional functionality JSONResponseMixin and
NgCRUDView
can be used together.