Angular + DjangoA match made in heaven
github.com/nnja/tweeter
Django Templates… are not my favorite
● Need to refresh the page to submit a form● Tough to write JS around template tags● Difficult to Unit Test● Template tags can be hard to grok for front
end devs
… also end tags are annoying
Forms get complex, fast.
Why Endpoints are Better (IMHO)
● Faster - no waiting for a page to reload● Swap frameworks - Ability to use any javascript
framework, and switch them out easily.● Reusable - Have a mobile app? Your backend is
already done!
Dogfooding
If your endpoints are public, you can eat your own dogfood by consuming them internally.
REST Frameworks are Standard
Front End Devs know how to use them.
AngularJS
● MVC - Responsibilities are separated● Single page app. That means no refreshes for new
content, and a better user experience● Scope - Variables are bound between JS & View -
no nasty JQuery● Easily Unit Tested
The bad
You have to use Javascript
If you don’t like it...
Use another framework
Excellent presentation on choosing a JS Framework
http://brianholt.me/
Let’s build a Tweeter http://github.com/nnja/tweeter
Requirements
1. Display a list of tweets from all Users2. Display my tweets (logged in User)3. Show my profile - username, etc.
Our endpoints are created w/ DRF
Django Rest Framework- Easily create a REST endpoint for your application.
Our Modelclass Tweet(models.Model):
user = models.ForeignKey(User)
text = models.CharField(max_length=140)
timestamp = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-timestamp']
Our endpoints
/api/users/
/api/tweets/
/api/users/:id
/api/tweets/:id
GET /api/tweets/
HTTP 200 OK
Vary: Accept
Content-Type: text/html; charset=utf-8
Allow: GET, POST, HEAD, OPTIONS
[
{
"text": "Bob is the coolest name EVAR",
"user": "bob",
"timestamp": "2014-08-29T18:51:19Z"
}
]
Configuring Angular
Step 1.
Include angular.js
Throw ng-app into one of your tags. Everything within those tags is now an angular app.
<html lang="en" ng-app="tweeterApp">
Angular tags and Django template tags conflict.
{{ }}
UH OH
Tell angular to use different tagsI like [[ this ]]
or use {% verbatim %} {% endverbatim %}
static/js/app.js
$interpolateProvider.startSymbol('[[').endSymbol(']]');
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
$resourceProvider.defaults.stripTrailingSlashes = false;
Angular Resources
A wrapper around a REST Endpoint at a location.
angular.module('tweeterApp.services', ['ngResource'])
.factory('Tweet', function($resource) {
return $resource('/api/tweets/:id/');
});
Default Actions{ 'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'} };
Creating a new objectvar newTeet = new Tweet();
newTweet.name = "Look, a tweet!";
newTweet.$save();
CallbacksTweet.get({id:123}, function(tweet){
console.log(tweet);
});
VS PromisesTweet.get({id:123})
.$promise.then(function(tweet) {
$scope.tweet = tweet;
});
Scope
You change a value in the controller, and it’s automagically updated in the view.
And vice versa.
Angular ControllerstweeterControllers.controller('TweetCtrl', function
TweetCtrl($scope, Tweet) {
...
});
The meatTweet.query(function(response) {
$scope.tweets = response;
});
$scope.submitTweet = function(text) {
var tweet = new Tweet({text: text});
tweet.$save(function(){
$scope.tweets.unshift(tweet);
})
}
Can’t get rid of all the templates
Used to pass information from django-land to angular.
Gives us our static URL so we can load assets (css/js)
Interacting with Django Templates<script type="text/javascript">
angular
.module('tweeterApp.services')
.factory('AuthUser', function() {
return {
id: "{{ user.id|default:''}}",
}
});
</script>
Angular UI Routing .config(function ($stateProvider, $urlRouterProvider) {
...
$urlRouterProvider.otherwise('/');
$stateProvider
.state('tweets', {
url: '/',
templateUrl: 'static/tweeter/partials/tweet-list.html',
controller: 'TweetCtrl',
})
};
Routing in Angular
Drop this in your base template
<div ui-view></div>
Depending on the route, the correct partial will be rendered and inserted.
Partials
Just vanilla HTML and Angular.
Keep them in an accessible static folder.
Demo time!
Bye Everybody!
@nnjagithub.com/nnja/tweeter