44

I want to integrate Angular 2 with Django and I have some questions to make.

  1. How can I change the interpolation syntax for Angular 2 from {{ }} to (( )) or something like this?

  2. How can I add the CSRF token from cookie to every HTTP post?

In Angular 1 I did something like this:

.config(function($httpProvider) {
    $httpProvider.defaults.xsrfCookieName = 'csrftoken';
    $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
});
  1. Is a good idea to integrate Angular 2 with Django?
Francesco Borzi
  • 56,083
  • 47
  • 179
  • 252
Rus Mine
  • 1,523
  • 1
  • 18
  • 29
  • 5
    Don't change the interpolation syntax. Django templates and Angular templates never need to mix; Angular templates are static files from Django's point of view. – Daniel Roseman Jan 08 '16 at 09:10
  • 7
    Also I'd suggest separating your Django back end from the Angular 2 front end completely. Use something like Django Rest Framework to create a ReST service that your Angular 2 front end can access. – Zyzle Jan 08 '16 at 09:24
  • what about [angular-jwt](https://github.com/auth0/angular-jwt) for your second question ? – hzitoun Jan 08 '16 at 11:51
  • the angular-jwt library is for angular1 version not for angular 2 ( things has changed with the new version of angular) and my example on how i configured my $httpProvider was working very good on the old version of angular. – Rus Mine Jan 08 '16 at 12:01
  • I think you should check this question. http://stackoverflow.com/questions/34464108/angular2-set-headers-for-every-request – Antano Jun 23 '16 at 09:01

4 Answers4

133

I would recommend a different approach to the overall design of your Angular2-based project.

An Angular2-based application is meant to be used as a fully contained application running in the browser (similar conceptually to how a mobile application runs on a mobile OS). There should be a very clear and abrupt separation between your Angular2 app and the backend.

With that in mind, you can certainly use Django for your backend but not in the way a traditional Django app would use the framework with server-side rendered forms and pages.

Instead, you would rather design your backend so that it exposes a RESTful API interface with JSON payloads (with POST/PUT used to create and update objects, GET to fetch/list, etc.) Then your Angular2 app would consume that API to create the user-facing experience.

When submitted, an Angular2 form for creating an object would issue an HTTP POST request to your backend containing JSON-formatted data as its payload (and not the traditional form encoded data resulting from an HTML form submission)

Good tooling options for creating your RESTful backend API would be Django REST Framework or Tastypie.

For authentication, you could use JWT (JSON Web Tokens) and there are good add-ons for Django REST Framework that support that.

That architecture has one major advantage: in the future, if the evolution of your system requires real native mobile clients (Android or iOS apps for example), you should be able to consume the exact same RESTful API for those native apps.

That architecture also has drawbacks such as the inability to use Django forms-handling goodness out-of-the-box.

Considering the above, here are responses to your original questions:

  1. How can I change the interpolation syntax for angular2 from {{ }} to (()) or something like this.

There would be no need for that using the approach I suggest.

  1. How can i add the csrf token from cookie to every http post ?

If using JWT you would not need CSRF validation. If using session-based authentication, you would still need it but you could pass it using an HTTP header, as Langley suggested.

  1. Is a good ideea to integrate Angular2 with Django ?

Subjective but I would say yes, definitely. However, you need to make sure you clearly separate the backend from the frontend. The backend should not respond with server-side generated HTML snippets or HTML forms. That should all be handled within your Angular2 app.

David M.
  • 2,602
  • 1
  • 15
  • 15
  • 2
    If you use JWT (which contains csrf_token) in HttpOnly cookie (to protect it from steal it by XSS) you need to use csrf_token in header of each requests. Then on server side you compare csrf_token from request header and from cookie - if they match then everything is ok and server can execute request action. – Kamil Kiełczewski Jul 07 '16 at 08:03
  • According to this [reddit thread](https://www.reddit.com/r/django/comments/2gsk5w/i_just_jumped_ship_from_tastypie_to/), [restless](https://github.com/toastdriven/restless) should be considered along with [Tastypie](https://github.com/django-tastypie/django-tastypie) as another worthy DRF alternative. – dave_k_smith Sep 07 '16 at 13:31
  • 2
    @dave_k_smith many options are available for creating REST APIs using Python, above specific tools it's the concept that's important to outline here – David M. Sep 08 '16 at 20:38
  • @1 i would disagree. in case you like to use i18n or other changes when deploying templates {$ $} the interpolation provider should be changed, thus they would be stripped by django api. – tlausch Sep 11 '16 at 16:13
  • So how to benifite of Angular 2 features if we are fun of django but not so fun of SPA since the project is so SEO driven ? – amine amine Apr 04 '17 at 09:25
  • @amineamine you don't make important architecture choices strictly based on being a fan or not of a technology or concept... you need to use what works best for your needs. There are options for SEO with Angular 2+ (i.e. server-side rendering, a.k.a. Angular Universal, now part of Angular 4.0.0), but if you don't actually need an SPA type architecture, please, please choose another UI framework – David M. Apr 05 '17 at 12:01
  • This told me nothing about how to set a POST request properly in angular2 to a django backend. Which seemed to be the primary nature of the question and what I am struggling with. –  Apr 19 '17 at 02:31
  • @SamanthaAtkins The question had 3 points, which put together led to believe the OP was trying to use Angular 2 in a way that it's not meant to be used. As for your specific question, there seems be an answer here: http://stackoverflow.com/questions/34494876/what-is-the-right-way-to-use-angular2-http-requests-with-django-csrf-protection – David M. Apr 20 '17 at 11:23
9

Hmm. All the three question I faced recently.

    1. Yes. It is definitely a great idea. Since you have the power of many python libraries as backend to perform whatever action you like combined with the power of angular. :D
    1. Works by injecting your own HTTP-Provider with Updated Default Request Options as Langley suggested. Edit: I recently found a nicer solution using angular2 cookie service. Which injects you CSRSFToken by providing a XSRFStrategy ;-)

A Drawback is that you require additional libs: NPM:Angular2-cookie

import { Injectable } from '@angular/core';
import { CookieService } from 'angular2-cookie/services/cookies.service';
import { HttpModule, Headers, BaseRequestOptions, RequestOptions, XSRFStrategy, CookieXSRFStrategy }    from '@angular/http';


@Injectable()
export class DefaultRequestOptions extends BaseRequestOptions{
    headers:Headers = new Headers({
        'Content-Type': 'application/json'
    });
}

@NgModule({
    imports:  [...
        HttpModule],
    declarations: [
        AppComponent, ...,
    ],
    bootstrap: [AppComponent],
    providers: [...
        CookieService,
        {
            provide: RequestOptions,
            useClass: DefaultRequestOptions
        },
        {
            provide: XSRFStrategy,
            useFactory: (cookieService) => {
                return new CookieXSRFStrategy('csrftoken', 'X-CSRFToken');
            },
            deps: [CookieService]
        }
    ]
})
export class AppModule {
    constructor(){
       // ther you go ;-)
    }
}

static default Interpolation config within your '@angular/compiler' module.

import { DEFAULT_INTERPOLATION_CONFIG } from '@angular/compiler'

// These values will be used if not provided by your Component.interpolation

DEFAULT_INTERPOLATION_CONFIG.start = '{$';
DEFAULT_INTERPOLATION_CONFIG.end= '$}';
ir0h
  • 311
  • 5
  • 9
tlausch
  • 1,000
  • 1
  • 7
  • 5
4

There is a verbatim tag in Django ,
which can be used to ignore the {{}} tag inside verbatim block
Check here

Anoop Reghuvaran
  • 329
  • 2
  • 10
0

1- You cannot change angular's template syntaxis.

2- I don't think Angular's 2 API is that ahead yet as to do it with simply setting up a variable, but there are automatic ways of doing it, check this question:

How to make Angular 2 send all requests as application/x-www-form-urlencoded

you can do something very similar except that you'd set the X-CSRFToken header instead, and grab the cookie value manually with something like this:

https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie

3- That question is to open to get a real answer. I personally wouldn't, maybe I would try @Zyzle idea of using Django for the backend, but start mixing up front end sintaxis of two frameworks, I wouldn't recommend it.

Community
  • 1
  • 1
Langley
  • 5,326
  • 2
  • 26
  • 42
  • I wasn't prepared to migrate to angular 2 but i think is very good for seo if you do something like this: {{ my django website description }} .that's why i asked if i can change the interpolation. but i see that i dont get any kind of conflict.by the way many thanks for your answer! – Rus Mine Jan 10 '16 at 19:07
  • 1- yes you can. use DEFAULT_INTERPOLATION_CONFIG from '@angular.compiler' and rewrite start and begin fields with your own marker. – tlausch Sep 11 '16 at 16:28