AngularJS + Django = A Perfect Match

This video is from DjangoCon US 2014 in Portland, Oregon, USA.

AngularJS + Django = A Perfect Match
0:31:33
Published September 17, 2014
29,851 views
217 likes

AngularJS is a powerful MVC framework that can easily integrate with Django templates.

Let's walk through integrating the two for fantastic results. The result is a fast, dynamic single page application.

Help us caption & translate this video!

http://amara.org/v/FOP2/

Summary

Nina Zakharenko argues that Django applications are better served by reusable API endpoints than by putting complex logic into Django templates, especially when building responsive single-page interfaces. She demonstrates a Twitter-like app using Django REST Framework and AngularJS, covering API serializers and routes, Angular configuration, CSRF handling, template-syntax conflicts, trailing slashes, resources, promises, controllers, scope binding, partials, and UI routing. The combination lets Angular consume and update Django data without full-page reloads while retaining Django templates for static paths and passing limited server-side information to the frontend.

Key takeaways

  • Django REST Framework endpoints can be reused by single-page web apps, internal tools, and native mobile clients.
  • AngularJS separates frontend responsibilities, binds controller data to templates through scope, and avoids full-page reloads.
  • Angular must be configured to coexist with Django, including alternate interpolation markers, CSRF tokens, and trailing-slash handling.
  • Angular resources provide convenient CRUD operations against REST endpoints, while promises support cleaner success and error handling than nested callbacks.
  • Angular partials and UI routing can replace most Django-rendered pages, although one Django template remains useful for static URLs and server-provided data.
  • The example Twitter app retrieves users and tweets, submits validated data, and displays new tweets immediately through Angular and Django REST Framework.

Summarised automatically from the transcript.

Chapters

  1. 0:00 Django Templates and API Endpoints The talk introduces the drawbacks of Django templates and the benefits of building reusable API endpoints.
  2. 3:28 AngularJS Overview AngularJS is presented as a testable MVC framework for building responsive single-page applications.
  3. 5:48 Tweeter Application Architecture The speaker outlines the sample Tweeter app, its requirements, and its Django REST Framework model and serializers.
  4. 9:39 API Endpoints and Responses The talk walks through the user and tweet endpoints and the JSON data they return.
  5. 10:25 AngularJS and Django Configuration The speaker explains including AngularJS, defining the Angular app, resolving template conflicts, configuring CSRF, and preserving trailing slashes.
  6. 15:07 AngularJS Resources The talk demonstrates AngularJS resources, REST actions, creating objects, and saving them through the API.
  7. 17:25 Callbacks and Promises The speaker compares callback-based resource requests with promise-based success and error handling.
  8. 19:04 Scopes and Controllers The talk introduces AngularJS scope binding and shows controllers for querying and submitting tweets.
  9. 21:28 Django Integration and UI Routing The speaker covers passing Django data into AngularJS and using partials, routes, and views instead of Django templates.
  10. 25:22 Testing and Debugging The talk briefly discusses testing, AngularJS error messages, browser debugging, and practical development techniques.
  11. 27:05 Application and API Demonstration The speaker demonstrates the completed Tweeter app and the Django REST Framework browsable API, including validation and user data.
  12. 30:59 Conclusion The presentation wraps up with an invitation to ask questions and discuss the technology afterward.

Transcript

3,888 words · auto-generated Show

Automatically transcribed, so expect mistakes in names and technical terms.

0:20

Speaker 1: Hello everyone, uh welcome in DjangoCon. My name is Nina Zakarenko. I work for Reddit and we've been using this stack pretty extensively on our internal tools and it's worked out really well for us. Um just show of hands, how many of you guys write JavaScript? No JavaScript? It's awesome. Fair amount of you. So I made a kind of a little sample app that goes through all the concepts that we've discussed we're gonna be discussing. So if you guys want to clone that, I'll be going through a lot of code that's uh in this app. And you guys can follow along. So kind of doing this a little bit differently.

1:07

Speaker 1: I think this will be a little bit more fun So Django templates are not my favorite. They're, yeah, deal with it. Don't mean to offend anyone here, but my point of view. So you know they're they're kind of really slow. If you want to submit a form, you have to wait for the whole page to refresh. Template tags are kind of hard to understand. If you forget to end one, your you know your stuff is broken. It can be hard to debug, it's difficult to unit test, and if you're actually working with a front-end dev, sometimes it's kind of difficult for them to pick up the template tags without knowing Python.

1:54

Speaker 1: And you know, and tags are pretty annoying. Uh so forms get complex really fast. You kinda sprinkle in a little validation logic over here and you know abuse some template logic over there and all of a sudden, you know, would you like meatballs with your spaghetti? So in my humble opinion, why endpoints are better? They're faster. You can have a single page app, you don't have to wait for the whole thing to reload. You can swap JavaScript frameworks pretty easily. There's a whole slew of them out there.

2:40

Speaker 1: And once you have your endpoints set up, they're reusable. So let's say you want to write a native mobile app, well, you know, your backend 's already there. So that's pretty awesome. And you can dog food. So if your endpoints are public, you can use them internally, kind of work out all the kinks, see what's working, see what isn't. Um they'll be the first one to find out if there are any problems. So that's really uh a huge benefit. The other nice thing is that Rust frameworks are standard. So you know if you have a new front-end dev, chances are that they've already seen this, they've worked with this kind of structure, it's easy for them to understand.

3:28

Speaker 1: It's nothing new and they can get started right away. So if you need a JavaScript framework, why not Angular? There's tons of benefits to Angular. It's an MVC framework. The responsibilities are separated. uh single page app, no refreshes, uh much better user experience. And the scope. is this magical thing. Uh it's a way to to bind variables between your front end and your controller So no jQuery, no crazy JavaScript magic. You set a variable on your scope and it's accessible in the template.

4:15

Speaker 1: Angular is also very easily unit tested. Much better I think than kind of comparing, you know, in your unit test, does my HTML match what I expect it to? It's kind of hard to be dynamic when you're doing that. So the bad, you have to use JavaScript. It kind of seems like a bunch of you already do, so that's good. But uh I overheard in the elevator the other day someone's like I don't like JavaScript, it's just too many curly braces and semi-cools Yeah, that's not a good reason not to like JavaScript. So you know obviously other languages are not as elegant as Python.

5:02

Speaker 1: But it's the language of the web. It's not going anywhere. You'd be doing yourself a really great disservice, uh, avoiding learning it because you don't like the way it looks So sorry to call you out random elevator person, but truth So if you don't like Angular in particular, it's pretty easy to just swap out to another JavaScript framework. You got React and you got Ember and you got Backbone. And who knows what's coming next. So they're they all have their strengths and weaknesses A great talk about that is

5:48

Speaker 1: my coworker Brian Holt. He did a presentation about choosing a JavaScript framework, what the strengths and weaknesses are. So if you guys can't read that, that's http brianholt. me. And I definitely recommend that you read it. It's one of those funky reveal. js presentations, so just make sure you hit the down arrow if the presentation seems a little bit short. So I put up that GitHub code link earlier. Here it is again for anyone who missed it. We're gonna go ahead and use all the concepts that we're learning today to build the Tweeter app.

6:35

Speaker 1: Um our requirements are pretty short. Probably won't be seeing this. You know, out in the wild pretty often, but uh we want to display a list of tweets for all users. Uh we want to narrow down that list and only get the tweets for uh the logged in user. And then we also want to show the profile for that logged in user And it doesn't take a ton of code to get this all together. It's actually pretty impressive. So uh the endpoints that I'm using are created with Django Rust framework. It's pretty easy to create a Rust endpoint for your application. I don't know if any of you were at my talk yesterday, but

7:22

Speaker 1: kind of explore that in more detail. But for those of you looking at the code, the beef of the DRF stuff is in serializers. py and permissions. py And then the routing is done in URLs. py. So here's our model. It's uh Pretty simple. We have a foreign key user because we want to know who made the tweet. We have a regular chart field for the text and a timestamp of when the tweet was created. When you turn away from the microphone, it's hard to hear you. This one? Yeah, you were turning the microphone. Actually, it's the one on your right. When you turn to the right, we can't hear you. Oh, um, this should be on.

8:08

Speaker 1: Oh, I see. Yeah. Oh sorry, how about I do this? Does that help? As long as you don't turn to the right. I'm just gonna talk to you all like this now. Alright, let me mess with this. Can I have to deal with the static while I do? No. How about that? Is that better?

8:53

Speaker 1: I'm just gonna have to shout. Or I can lock one phone. Um sure, yeah. How's that? Testing, testing Good? Okay. I'm gonna take this contraption off then and turn it off. Can everyone hear me now? Yeah, awesome. All right. Um you know, just because people couldn't hear me, uh could you raise your hands and ask if there are any concepts you'd like me to re-explain? Y'all good? Alright.

9:39

Speaker 1: So our our endpoints are gonna look like this. They're really simple. We have uh endpoint to fetch all the users, an endpoint to fetch uh just one user, an endpoint to fetch all the tweets. And then an endpoint to fetch a tweet by ID. So when we call our tweets endpoint, this is the kind of uh response we're gonna get It's just a list of JSON tweets that contain the fields that we've defined in our Django Rust framework serializer. The next thing we're going to talk about is configuring

10:25

Speaker 1: Angular for Django. There are definitely a few gotchas that you need to be aware of. When you're using it, you know, right off the bat. So the first thing you need to do is fetch an Angular file and include it in your template. For my mini project, I just fetched it and put it in a local lib folder, but It's uh best to use CDN. If there are any updates, you kind of get them automatically. You don't have to worry about maintaining yet another library. And uh the way we enable our front end to be angular is by using an ng app tag. Can

11:11

Speaker 1: everyone see the bottom of the screen? Yeah? Okay. So the most common place you would put it is in the HTML. uh or the body but if you only want you know some little part of your app to be angular you can even throw it in a div. So really flexible I called my Angular app Tweeter app. So very creative and original. So, uh oh. Angular tags and Jangular template tags conflict. They're both double curly braces and that's kind of a problem. If you just try to throw some Angular on your Django page, some

11:59

Speaker 1: things are gonna barf and not very pretty So the way to get around that is either to tell Angular to use a different kind of tag. So uh for example, I like using uh double square brackets Or uh you can use the Django template verbatim tag. So I very much prefer the first way. Because if you go the second route, you're just gonna have tons of chunks of verbatim tags all over your template. It gets messy. Uh not really great but it's an option for you if you want to use it. So this is how we tell Angular to use a different kind of bracket.

12:46

Speaker 1: It's actually a you know really great feature that they've provided this and we have options. The second thing we want to configure is our C CSRF tokens. So if you read the Django docs on Ajax, they'll they'll tell you to do this. So you need to tell Angular that, you know, this is what the CRS tokens are, this is what they're called And then on your in your Django views, you want to use ensure CSRF token to make sure that um To make sure that that token is generated, even if the CSRF token tag is not present in the template. So kind of handy and and cleaner

13:31

Speaker 1: and I think it's a lot more explicit too, you know, when you're looking at the view. If not all your views are CSRF protected by middleware, you know which ones are um you know which ones are gonna be passing that token uh back. The next important thing in our configuration file is we want to tell Angular to stop stripping trailing uh slashes. So I don't know why it does that, but That's not really uh that doesn't really work with Django, because Django loves trailing slashes. They're everywhere. So uh this is actually a new feature in Angular 3. So be mindful of that. If you're using an older version of Angular, there's some

14:21

Speaker 1: Kind of hacky ways to get around it. You have to add on a trailing slash that's escaped in a string. And then you can't use some of that Angular magic where it kind of can guess what your endpoints are structured like based on Rust. And you have to do a little bit more configuration on the Angular side as well So, this is what uh an angular resource looks like. It's uh it's a factory that lets you create a resource object and uh based off a Rusty endpoint and interact with it really simply.

15:07

Speaker 1: So to kind of walk through the code, tweeterapp. services is what my services module is called. And then Ng resource is actually a separate JavaScript include that you have to be mindful of because it's not part of the core Angular code. And here we define a factory that's based on our tweets. Uh so when we create an object Called tweet in JavaScript land, it it's aware of this URL. And there's some kind of magical binding going on. So here are some of the default actions you get with the Angular resource.

15:53

Speaker 1: You kind of get all those H E G B verbs. It's aware of uh Get so if you have an ID defined in your resource, uh like I did here. So uh There's that uh the I don't know what what is that symbol called the two two dots colon? Colon yes so uh colon ID is kind of uh an important thing to note there Because when you use this kind of built-in method, you call get, it knows that an ID is expected. And so when you pass one in, Angular knows that you're getting a single resource, it's an object. kind of does magic and transforms it to be that way.

16:38

Speaker 1: Whereas when you call query, it knows to expect a collection and it's going to call the root of that endpoint without the ID. Does that make sense to everyone? See some nods? No nods? Yeah? Alright. So here's how we would create a new object. It's really simple. It's not quite as messy as something like jQuery Ajax. So we called our resource tweet. We can just call new tweet. Set some properties on it and call save. And that's Angular Magic for you. It's pretty awesome.

17:25

Speaker 1: So there are two ways to interact with these resources. The first way is callbacks. I'm sure many of you have heard of or experienced Callback Hell. It's out there. So when you call uh tweet. get and you pass in an ID, if there's if that's kind of it, what you're gonna get back is uh It's it's a promise. So you don't you you don't get anything back right away. You kind of have to know when the server has responded and then do something with that data. So uh here's the callback format. We're passing in a function, uh, we're taking in a tweet, and then we can do stuff with that object once uh that server has returned.

18:14

Speaker 1: The newer way of doing this is um it's called promises. They're much cleaner code, uh in my opinion. You can chain them. Uh so instead of passing uh passing in a callback function, you instead call dot promise then And then your function that gets called when that data is returned is there. And you can chain these promises. So this promise only takes care of a successful request. If there's an error, you should chain another promise on, and then you'll get that error code back and the status, and you can do something with that. So, for example, if it's not authorized, you know, display the correct message to the user.

19:04

Speaker 1: So the scope is, like I mentioned earlier, really my favorite thing about Angular. I like to call it auto-magical. You change something in your controller, it's uh displayed on the front end right away. You change something you know on your front end in your template and it's there in the controller, magic. Magic. That's how I felt when I first learned about it. So uh let's move on to controllers. Our the syntax for creating one is kind of similar to how you would uh create a resource. So here tweet CTRL is the name of our controller.

19:53

Speaker 1: And we call a function, but an important thing to note here is that these are dependencies. So by passing in these arguments, we're telling the controller that we need a handle on scope, and we also need a handle on tweet. And that's our that resource that we created. So now we can freely use it in the controller. Oops, I'm not still. So here's the meat of our controller. We have our query function, and that satisfies our first requirement of wanting to get all the tweets that exist.

20:40

Speaker 1: Here you see I'm calling uh using a callback, and when that query returns, we want to set scope. tweets to the response. So as soon as this function is done, they pop up. The other thing, uh the other function in our controller is used to submit a tweet. So we use that same syntax that we saw, we create a new tweet , we pass in the data that was in that input box, and then we call save on it. And the last thing that we do is pop that tweet right onto the top of our stack of current tweets, and it's displayed right away.

21:28

Speaker 1: So fortunately you can't get rid of all the Django templates. You need one It allows you to pass information back and forth from Django land to Angular land. It lets us know what the static URL path is. So that we can include those files. It's it's kind of useful, so can't get rid of it. Here's an example of how you would pass uh some template data back into Angular. It's a little bit hacky, but it works. And we actually throw this on our base template page, and it instantiates a quick and dirty little service.

22:19

Speaker 1: I call it auth user. And it kind of runs a piece of code on the page and displa uh returns that result. So we can uh actually go into the Django user and get some uh useful information back from it in this case the ID I'm not sure where I found this hack, but it's actually been really useful. So whoever the author is, thank you. So this is how we do UI routing in Angular. Instead of using Django templates, we're going to be using partials. There's a lot going on on this page. So let's kind of go through it one by one.

23:08

Speaker 1: The first thing that we note is that URL provider the default That's the default route. So if someone tries to type in a bunch of stuff in that URL bar, they're just gonna get kicked back to here. The URL is what that URL will look like to the user The template URL is where that partial is stored. And the controller is kind of the important bit. That lets you know, that lets Angular know which controller to associate to which template. There's a different way of doing it that's similar to ng app. You can throw that controller into any HTML tag. But I find this way to be much cleaner.

23:54

Speaker 1: All your controllers are defined in one place. You instantly know where they're getting called. So writing an Angular is pretty simple. You drop UIView into a div anywhere on your page, and that's where the partials are going to be dropped in. So it it's a lot different than something that include because it's also error of state. You can pass variables back and forth. You can use them as conditionals. So very powerful. Yeah, your partials are just vanilla HTML and Angular. No Django necessary.

24:40

Speaker 1: Uh I like to keep them in an accessible static folder. Yes.

24:48

Speaker 2: What's a partial?

24:49

Speaker 1: Um I can show you guys one.

24:52

Speaker 2: to short for something more descriptive.

24:55

Speaker 1: No. Let's look at some code. So if

25:03

Speaker 3: we can reserve our questions for the end of the talk this way, she can just uh let's see.

25:22

Speaker 1: Okay, I'll have to show it to you guys afterwards. Chrome full screen does not want to give up So I didn't include any information about testing in this talk. I wasn't sure if I would have time, but test all the things. Do it It's just so much easier and nicer. The Angular documentation is pretty good. My my experience with it, you know, there there are some cons. The biggest one to me was um When you get an error in your Angular code, it's pretty indecisurable. Indecipable. Excuse me. It's you know all anonymous functions and callbacks

26:07

Speaker 1: and You something happens, you're just like wet. But it it kind of figuring out what's going wrong comes with experience. So just keep at it. Don't get too frustrated. Use that debugger command uh sorry debugger statement in in your JavaScript. Uh if you have Chrome DevTools open, it'll just stop there. Use you know use prints. They're okay. We all use them. It's uh it's okay to admit it. Uh so demo time. Crossing my fingers because this didn't go so well the last time. But I'm gonna show you guys my Twitter app in action.

27:05

Speaker 1: Here it is in all of its glory. Uh here we have all the tweets From all of our users. They're really cool and creative. We all want to read them. And here's our my tweets view. Boom, it's so fast. Such a nice user experience. No page reload, it's pretty instantaneous, and it doesn't, you know, even when you have a ton of data, it's not super bogged down. And here we have our our profile view. So I know I'm a great web designer. Thank you guys very much. But the the cool thing that I want to look at is uh

27:55

Speaker 1: See if I type that right. Yeah. Here's our our Django Rust framework, browsable API. This is awesome. Definitely one of the uh features that I love most about it. Super easy to use. For example, here's a drop-down. Oops. Yeah, demo time. We can call options and kind of see what's available on our API. Here it this is the route, so from here we can kind of navigate down, look at our tweets, we get a tweet list. So here we can see all the data that's coming back to Angular. We can also

28:40

Speaker 1: submit data back. So We can either do it from raw data or HTML. I have a or an HTML form actually, which is really nice. So I have a validator set in place that's gonna return an error if My tweet is less than five characters. See, um I get a bad request with the error message that I specified. Django 's framework is also really smart. So I have a model field that is only 140 characters. So I put a bunch of text in here. I always feel like I'm, you know, doing this.

29:27

Speaker 1: Um long enough. Let's see. Here I have a better idea. Copy and paste. We'll get another bad request. I can't see this on my screen, so I'm just gonna assume everything is going great. Um so let's kind of let's go back to our API route. And uh take a quick look at our users on point. So here's where we, oh

30:14

Speaker 1: here we go, look at my awesome tweet. Here's uh where we get back all of our users, properties about them, first name, last name, username, and then uh collection of all their tweets So this was super easy to create Come on, Google Drive. The internet was down earlier today, so that was definitely very, very nerve-wracking. But um just put that up.

30:59

Speaker 1: That's uh it for my presentation. Feel free to find me afterwards if you have questions. I love to talk about the stuff and I hope you guys enjoyed my talk.

Questions this talk answers

Why use API endpoints instead of Django templates?

Endpoints support faster single-page applications without full-page reloads, can be reused by other clients such as native mobile apps, and are easier for frontend developers to work with. They also make it possible to dogfood and test a public API internally.

Discussed at 1:54

How do I use AngularJS in a Django template?

Include AngularJS in the template, preferably from a CDN, and mark the Angular portion with an `ng-app` directive. The Angular app can cover the whole HTML or just a specific element such as a `div`.

Discussed at 10:25

How do I prevent AngularJS and Django template tags from conflicting?

Configure AngularJS to use different interpolation markers, such as double square brackets, or wrap Angular markup in Django’s `verbatim` tag. The speaker prefers changing Angular’s delimiters because it avoids scattering `verbatim` blocks throughout the template.

Discussed at 11:59

How do I configure CSRF protection for AngularJS and Django?

Tell AngularJS which CSRF cookie and header names Django uses, and use Django’s `ensure_csrf_cookie` so the token is generated even when the CSRF template tag is not present. This makes the token available for Angular’s requests.

Discussed at 12:46

How do I stop AngularJS from removing trailing slashes from Django URLs?

Configure AngularJS not to strip trailing slashes, since Django commonly expects them. In older Angular versions, the workaround requires escaped trailing slashes and more explicit URL configuration.

Discussed at 13:31

How do AngularJS resources work with Django REST Framework endpoints?

An AngularJS resource is a factory tied to an API URL, providing methods for common HTTP operations. `get` expects an individual resource when given an ID, while `query` requests the collection endpoint; creating and saving an object can be done with `new` and `save`.

Discussed at 14:21

How do I handle asynchronous AngularJS resource requests?

Resource calls return promises rather than data immediately. You can use callbacks, or chain promise handlers for successful responses and errors; error handlers receive information such as the status code so the UI can show an appropriate message.

Discussed at 17:25

How does AngularJS scope bind data between controllers and templates?

Scope automatically synchronizes controller and template data: changes made in the controller appear in the UI, and changes made in the template are available to the controller. This avoids manually wiring together DOM updates with jQuery-style code.

Discussed at 19:04

How do I pass Django user data into AngularJS?

Keep a base Django template to provide values such as static paths and server-side data. The talk demonstrates creating a small AngularJS service that reads information from the Django user, such as the user ID.

Discussed at 21:28

How do I set up client-side routing with AngularJS and Django?

Use AngularJS routes and partial templates instead of separate Django templates for each view. Define the default route, URL, partial’s template URL, and associated controller, then place a `ui-view` element in the page where the partial should be rendered.

Discussed at 22:19

Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.

More videos from DjangoCon US