djangocon 2014 angular + django

Post on 30-Nov-2014

751 Views

Category:

Software

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

Djangocon 2014 angular + django

TRANSCRIPT

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

top related