SlideShare uma empresa Scribd logo
1 de 49
Baixar para ler offline
Django Rest Framework
and React and Redux,
Oh My!
I’m Eric Palakovich Carr.
Co-Founder & Chief Architect at
Previously:
What this talk is not
• A comprehensive tutorial
• A deep dive into how these technologies works
• You WILL need to go and learn this stuff on your
own after this talk
{% extends "base.html" %}
{% load staticfiles %}
{% block title %}Some Awesome Django Website{% endblock %}
{% block extrahead %}
<link rel="stylesheet" href="{% static "some.css" %}"/>
<link rel="stylesheet" href="{% static "even_more.css" %}"/>
{% endblock %}
{% block body %}
<!-- some content in Django template -->
<div id="todolist"></div>
<!-- more content in Django template -->
{% endblock %}
Javascript Ecosystem
• We’ll be using NPM to manage your packages
• We’ll be using webpack to handle bundling our
assets.
• We’ll be using scotch to burn away the memories of
configuring the build system for our project.
in a nutshell
• The pip & cheeseshop / pypi of javascript
• packages.json works like requirements.txt &
setup.py
• `npm init` in directory with packages.json generates
node_modules. Kinda like a virtualenv directory.
• packages.json also can act like your `manage.py`
for your javascript code, but you populate it with
custom commands.
Building for Javascript
• Start coding your project, using `npm install some-package —
save` as you go. This creates and maintains your package.json.
• Setup the config file for your build tool (webpack.config.js,
gulpfile.js, Gruntfile, etc)
• Add configs for Babel, minification, and other JS stuff
• Add configs LESS, SASS, and other CSS stuff
• Plus source mapping, tests, linters, sprite sheets, etc
• Run your tool to generate bundles, having them save into your
static directory for Django to pick up.
{% extends "base.html" %}
{% load staticfiles %}
{% block title %}Some Awesome Django Website{% endblock %}
{% block extrahead %}
<link rel="stylesheet" href="{% static "bundle.css" %}"/>
<link rel="stylesheet" href="{% static "some.css" %}"/>
<link rel="stylesheet" href="{% static "even_more.css" %}"/>
{% endblock %}
{% block body %}
<!-- some content in Django template -->
<div id="todolist"></div>
<script src="{% static "bundle.js" %}"></script>
<!-- more content in Django template -->
{% endblock %}
{% extends "base.html" %}
{% load staticfiles %}
{% load render_bundle from webpack_loader %}
{% block title %}Some Awesome Django Website{% endblock %}
{% block extrahead %}
<link rel="stylesheet" href="{% static "some.css" %}"/>
<link rel="stylesheet" href="{% static "even_more.css" %}"/>
{% endblock %}
{% block body %}
<!-- some content in Django template -->
<div id="todolist"></div>
{% render_bundle 'main' 'js' %}
<!-- more content in Django template -->
{% endblock %}
DEMO
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import TodoHeader from './TodoHeader.jsx';
ReactDOM.render(
(
<div className="todoWidget">
<TodoHeader listName="todos" />
</div>
),
document.getElementById('todolist')
);
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import TodoHeader from './TodoHeader.jsx';
ReactDOM.render(
(
<div className="todoWidget">
<TodoHeader listName="todos" />
</div>
),
document.getElementById('todolist')
);
JSX
// TodoHeader.jsx
import React, { Component } from 'react';
export default class TodoHeader extends Component {
render() {
return (
<header className='todoHeadCmp'>
<h1>{this.props.listName}</h1>
</header>
);
}
}
JSX
// TodoHeader.jsx
import React, { Component } from 'react';
export default class TodoHeader extends Component {
render() {
return (
<header className='todoHeadCmp'>
<h1>{this.props.listName}</h1>
</header>
);
}
}
// TodoHeader.jsx
import React, { Component } from 'react';
export default class TodoHeader extends Component {
render() {
return React.createElement(
"header",
{className: "todoHeadCmp"},
React.createElement(
"h1",
null,
this.props.listName,
)
);
}
}
export default class TodoTextInput extends Component {
constructor(props, context) {
super(props, context);
this.state = {
text: this.props.text || ''
};
}
handleSubmit(e) {
const text = e.target.value.trim();
if (e.which === 13) {
this.props.onSave(text);
}
}
handleChange(e) {
this.setState({ text: e.target.value });
}
render() {
return (
<input type='text'
value={this.state.text}
onChange={::this.handleChange}
onKeyDown={::this.handleSubmit} />
);
}
}
React Component Lifecycle
• componentWillMount
• componentDidMount
• componentWillReceiveProps
• shouldComponentUpdate
• componentWillUpdate
• componentDidUpdate
• componentWillUnmount
Django Rest Framework
• The Web browsable API is a huge usability win for your developers.
• Authentication policies including packages for OAuth1a and
OAuth2.
• Serialization that supports both ORM and non-ORM data sources.
• Customizable all the way down - just use regular function-based
views if you don't need the more powerful features.
• Extensive documentation, and great community support.
• Used and trusted by large companies such as Mozilla and
Eventbrite.
Model->Serializer->ViewSet
class Todo(models.Model):
text = models.CharField(max_length=300)
marked = models.BooleanField(default=False)
class TodoSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Todo
fields = ('id', 'text', 'marked')
class TodoViewSet(viewsets.ModelViewSet):
queryset = Todo.objects.all()
serializer_class = TodoSerializer
Demo
Three Principles of Redux
• Single source of truth
• State is read-only
• Changes are made with pure functions
Redux State Tree / Store
{
visibilityFilter: 'SHOW_ALL',
todos: [
{
text: 'Consider using Redux',
completed: true,
},
{
text: 'Keep all state in a single tree',
completed: false
}
]
}
Reducers
{
visibilityFilter: 'SHOW_ALL',
todos: [
{
text: 'Consider using Redux',
completed: true,
},
{
text: 'Keep all state in a single tree',
completed: false
}
]
}
import * as types from '../constants/ActionTypes';
const initialState = [];
export default function todos(state=initialState, action) {
switch (action.type) {
case types.ADD_TODO:
return [...state, action.todo];
case types.DELETE_TODO:
return state.filter(todo =>
todo.id !== action.id
);
case types.EDIT_TODO:
return state.map(todo =>
todo.id === action.todo.id ? action.todo : todo
);
default:
return state;
}
}
store.dispatch({
type: 'ADD_TODO',
todo: {
text: "Check how much time is left",
marked: false
}
})
store.dispatch({
type: 'SET_VISIBILITY_FILTER',
filter: 'SHOW_COMPLETED'
})
Presentational Components
• Are concerned with how things look.
• Use props for displaying everything
• Do not manage state at all
• Don’t emit actions, but may take callbacks that do via
props
<MyComponent
title=“No state, just props.”
barLabels={["MD", "VA", "DE", "DC"]}
barValues={[13.626332, 47.989636, 9.596008, 28.788024]}
/>
Container Component
• Are concerned with how things work.
• Responsible for providing data to presentational
components via props
• Also responsible for handling state changes
triggered inside a presentation component via
callback prop. These state changes are often
done via dispatching an action.
class TodoApp extends Component {
componentDidMount() {
this.props.actions.getTodos();
}
render() {
const { todos, actions } = this.props;
return (
<div>
<Header addTodo={actions.addTodo} />
<MainSection todos={todos} actions={actions} />
</div>
);
}
}
function mapState(state) {
return {
todos: state.todos
};
}
function mapDispatch(dispatch) {
return {
actions: bindActionCreators(TodoActions, dispatch)
};
}
export default connect(mapState, mapDispatch)(TodoApp);
Wiring Redux to DRF
• Python package “django-js-reverse" for getting
your url routes in your javascript
• NPM package “redux-promise”
import * as types from '../constants/ActionTypes';
function deleteTodo(id) {
return fetch(Urls.todo_detail(id), {
method: 'delete',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': getCookie('csrftoken')
},
}).then(() => ({
type: types.DELETE_TODO,
id: id
}));
}
// In a component somewhere else
store.dispatch(deleteTodo(this.props.todo.id))
import * as types from '../constants/ActionTypes';
import * as api from ‘../path/to/MyApiLibrary';
function deleteTodo(id) {
return api.deleteTodo(id).then(() => ({
type: types.DELETE_TODO,
id: id
}));
}
// In a component somewhere else
store.dispatch(deleteTodo(this.props.todo.id))
DEMO
Quick Recap
i.e. TL;DR
You need a build tool to
create bundles.
Webpack is nice for this.
{% extends "base.html" %}
{% load staticfiles %}
{% block title %}Some Awesome Django Website{% endblock %}
{% block extrahead %}
<link rel="stylesheet" href="{% static "bundle.css" %}"/>
<link rel="stylesheet" href="{% static "some.css" %}"/>
<link rel="stylesheet" href="{% static "even_more.css" %}"/>
{% endblock %}
{% block body %}
<!-- some content in Django template -->
<div id="todolist"></div>
<script src="{% static "bundle.js" %}"></script>
<!-- more content in Django template -->
{% endblock %}
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import TodoHeader from './TodoHeader.jsx';
ReactDOM.render(
(
<div className="todoWidget">
<TodoHeader listName="todos" />
</div>
),
document.getElementById('todolist')
);
// TodoHeader.jsx
import React, { Component } from 'react';
export default class TodoHeader extends Component {
render() {
return (
<header className='todoHeadCmp'>
<h1>{this.props.listName}</h1>
</header>
);
}
}
class Todo(models.Model):
text = models.CharField(max_length=300)
marked = models.BooleanField(default=False)
class TodoSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Todo
fields = ('id', 'text', 'marked')
class TodoViewSet(viewsets.ModelViewSet):
queryset = Todo.objects.all()
serializer_class = TodoSerializer
import * as types from '../constants/ActionTypes';
const initialState = [];
export default function todos(state=initialState, action) {
switch (action.type) {
case types.ADD_TODO:
return [...state, action.todo];
case types.DELETE_TODO:
return state.filter(todo =>
todo.id !== action.id
);
case types.EDIT_TODO:
return state.map(todo =>
todo.id === action.todo.id ? action.todo : todo
);
default:
return state;
}
}
import * as types from '../constants/ActionTypes';
function deleteTodo(id) {
return fetch(Urls.todo_detail(id), {
method: 'delete',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': getCookie('csrftoken')
},
}).then(() => ({
type: types.DELETE_TODO,
id: id
}));
}
// In a component somewhere else
store.dispatch(deleteTodo(this.props.todo.id))
Thanks!
Eric Palakovich Carr
@bigsassy on twitter and github
example repo at https://github.com/bigsassy/drf-react-redux

Mais conteúdo relacionado

Mais procurados

Django app deployment in Azure By Saurabh Agarwal
Django app deployment in Azure By Saurabh AgarwalDjango app deployment in Azure By Saurabh Agarwal
Django app deployment in Azure By Saurabh Agarwalratneshsinghparihar
 
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?Srijan Technologies
 
Aligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsAligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsMatthew Beale
 
Web development with django - Basics Presentation
Web development with django - Basics PresentationWeb development with django - Basics Presentation
Web development with django - Basics PresentationShrinath Shenoy
 
SaaSy maps - using django-tenants and geodjango to provide web-gis software-a...
SaaSy maps - using django-tenants and geodjango to provide web-gis software-a...SaaSy maps - using django-tenants and geodjango to provide web-gis software-a...
SaaSy maps - using django-tenants and geodjango to provide web-gis software-a...Anusha Chickermane
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rulesSrijan Technologies
 
The Django Book - Chapter 5: Models
The Django Book - Chapter 5: ModelsThe Django Book - Chapter 5: Models
The Django Book - Chapter 5: ModelsSharon Chen
 
Building an API with Django and Django REST Framework
Building an API with Django and Django REST FrameworkBuilding an API with Django and Django REST Framework
Building an API with Django and Django REST FrameworkChristopher Foresman
 
The DOM is a Mess @ Yahoo
The DOM is a Mess @ YahooThe DOM is a Mess @ Yahoo
The DOM is a Mess @ Yahoojeresig
 
Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)Jacob Kaplan-Moss
 
Caldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW WorkshopCaldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW WorkshopCalderaLearn
 
Intoduction to Play Framework
Intoduction to Play FrameworkIntoduction to Play Framework
Intoduction to Play FrameworkKnoldus Inc.
 
Django multi-tier
Django multi-tierDjango multi-tier
Django multi-tiersmirolo
 

Mais procurados (20)

Django app deployment in Azure By Saurabh Agarwal
Django app deployment in Azure By Saurabh AgarwalDjango app deployment in Azure By Saurabh Agarwal
Django app deployment in Azure By Saurabh Agarwal
 
Django a whirlwind tour
Django   a whirlwind tourDjango   a whirlwind tour
Django a whirlwind tour
 
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
 
Aligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsAligning Ember.js with Web Standards
Aligning Ember.js with Web Standards
 
Web development with django - Basics Presentation
Web development with django - Basics PresentationWeb development with django - Basics Presentation
Web development with django - Basics Presentation
 
Django
DjangoDjango
Django
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
 
AJAX Transport Layer
AJAX Transport LayerAJAX Transport Layer
AJAX Transport Layer
 
SaaSy maps - using django-tenants and geodjango to provide web-gis software-a...
SaaSy maps - using django-tenants and geodjango to provide web-gis software-a...SaaSy maps - using django-tenants and geodjango to provide web-gis software-a...
SaaSy maps - using django-tenants and geodjango to provide web-gis software-a...
 
Tango with django
Tango with djangoTango with django
Tango with django
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
 
The Django Book - Chapter 5: Models
The Django Book - Chapter 5: ModelsThe Django Book - Chapter 5: Models
The Django Book - Chapter 5: Models
 
Building an API with Django and Django REST Framework
Building an API with Django and Django REST FrameworkBuilding an API with Django and Django REST Framework
Building an API with Django and Django REST Framework
 
The DOM is a Mess @ Yahoo
The DOM is a Mess @ YahooThe DOM is a Mess @ Yahoo
The DOM is a Mess @ Yahoo
 
Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)
 
Caldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW WorkshopCaldera Learn - LoopConf WP API + Angular FTW Workshop
Caldera Learn - LoopConf WP API + Angular FTW Workshop
 
Writing Pluggable Software
Writing Pluggable SoftwareWriting Pluggable Software
Writing Pluggable Software
 
Ant
AntAnt
Ant
 
Intoduction to Play Framework
Intoduction to Play FrameworkIntoduction to Play Framework
Intoduction to Play Framework
 
Django multi-tier
Django multi-tierDjango multi-tier
Django multi-tier
 

Destaque

Django Admin (Python meeutp)
Django Admin (Python meeutp)Django Admin (Python meeutp)
Django Admin (Python meeutp)Ines Jelovac
 
Starters with Django
Starters with Django Starters with Django
Starters with Django BeDjango
 
Efficient Django
Efficient DjangoEfficient Django
Efficient DjangoDavid Arcos
 
Python RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutionsPython RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutionsSolution4Future
 
David Threets Professional Persona Project
David Threets Professional Persona Project David Threets Professional Persona Project
David Threets Professional Persona Project David Threet
 
REST API Doc Best Practices
REST API Doc Best PracticesREST API Doc Best Practices
REST API Doc Best PracticesMarta Rauch
 
Magic Methods (Python meetup)
Magic Methods (Python meetup)Magic Methods (Python meetup)
Magic Methods (Python meetup)Ines Jelovac
 
тайны фокусов
тайны фокусовтайны фокусов
тайны фокусовlavrenteva
 
REST API Best (Recommended) Practices
REST API Best (Recommended) PracticesREST API Best (Recommended) Practices
REST API Best (Recommended) PracticesRasheed Waraich
 
DJANGO-REST-FRAMEWORK: AWESOME WEB-BROWSABLE WEB APIS
DJANGO-REST-FRAMEWORK: AWESOME WEB-BROWSABLE WEB APISDJANGO-REST-FRAMEWORK: AWESOME WEB-BROWSABLE WEB APIS
DJANGO-REST-FRAMEWORK: AWESOME WEB-BROWSABLE WEB APISFernando Rocha
 
REST Easy with Django-Rest-Framework
REST Easy with Django-Rest-FrameworkREST Easy with Django-Rest-Framework
REST Easy with Django-Rest-FrameworkMarcel Chastain
 
django-and-postgresql
django-and-postgresqldjango-and-postgresql
django-and-postgresqlOleg Churkin
 
Getting Started With Django
Getting Started With DjangoGetting Started With Django
Getting Started With Djangojeff_croft
 
OAuth2: Uma abordagem para segurança de aplicações e APIs REST - Devcamp 2014
OAuth2: Uma abordagem para segurança de aplicações e APIs REST  - Devcamp 2014OAuth2: Uma abordagem para segurança de aplicações e APIs REST  - Devcamp 2014
OAuth2: Uma abordagem para segurança de aplicações e APIs REST - Devcamp 2014Tiago Marchetti Dolphine
 
тайны фокусов
тайны фокусовтайны фокусов
тайны фокусовlavrenteva
 
Django rest framework tips and tricks
Django rest framework   tips and tricksDjango rest framework   tips and tricks
Django rest framework tips and tricksxordoquy
 
Django 實戰 - 自己的購物網站自己做
Django 實戰 - 自己的購物網站自己做Django 實戰 - 自己的購物網站自己做
Django 實戰 - 自己的購物網站自己做flywindy
 
那些年,我用 Django Admin 接的案子
那些年,我用 Django Admin 接的案子那些年,我用 Django Admin 接的案子
那些年,我用 Django Admin 接的案子flywindy
 

Destaque (20)

Django Admin (Python meeutp)
Django Admin (Python meeutp)Django Admin (Python meeutp)
Django Admin (Python meeutp)
 
Free django
Free djangoFree django
Free django
 
Starters with Django
Starters with Django Starters with Django
Starters with Django
 
Efficient Django
Efficient DjangoEfficient Django
Efficient Django
 
Python RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutionsPython RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutions
 
David Threets Professional Persona Project
David Threets Professional Persona Project David Threets Professional Persona Project
David Threets Professional Persona Project
 
REST API Doc Best Practices
REST API Doc Best PracticesREST API Doc Best Practices
REST API Doc Best Practices
 
Magic Methods (Python meetup)
Magic Methods (Python meetup)Magic Methods (Python meetup)
Magic Methods (Python meetup)
 
тайны фокусов
тайны фокусовтайны фокусов
тайны фокусов
 
REST API Best (Recommended) Practices
REST API Best (Recommended) PracticesREST API Best (Recommended) Practices
REST API Best (Recommended) Practices
 
DJANGO-REST-FRAMEWORK: AWESOME WEB-BROWSABLE WEB APIS
DJANGO-REST-FRAMEWORK: AWESOME WEB-BROWSABLE WEB APISDJANGO-REST-FRAMEWORK: AWESOME WEB-BROWSABLE WEB APIS
DJANGO-REST-FRAMEWORK: AWESOME WEB-BROWSABLE WEB APIS
 
Парсер: что? зачем? как?
Парсер: что? зачем? как?Парсер: что? зачем? как?
Парсер: что? зачем? как?
 
REST Easy with Django-Rest-Framework
REST Easy with Django-Rest-FrameworkREST Easy with Django-Rest-Framework
REST Easy with Django-Rest-Framework
 
django-and-postgresql
django-and-postgresqldjango-and-postgresql
django-and-postgresql
 
Getting Started With Django
Getting Started With DjangoGetting Started With Django
Getting Started With Django
 
OAuth2: Uma abordagem para segurança de aplicações e APIs REST - Devcamp 2014
OAuth2: Uma abordagem para segurança de aplicações e APIs REST  - Devcamp 2014OAuth2: Uma abordagem para segurança de aplicações e APIs REST  - Devcamp 2014
OAuth2: Uma abordagem para segurança de aplicações e APIs REST - Devcamp 2014
 
тайны фокусов
тайны фокусовтайны фокусов
тайны фокусов
 
Django rest framework tips and tricks
Django rest framework   tips and tricksDjango rest framework   tips and tricks
Django rest framework tips and tricks
 
Django 實戰 - 自己的購物網站自己做
Django 實戰 - 自己的購物網站自己做Django 實戰 - 自己的購物網站自己做
Django 實戰 - 自己的購物網站自己做
 
那些年,我用 Django Admin 接的案子
那些年,我用 Django Admin 接的案子那些年,我用 Django Admin 接的案子
那些年,我用 Django Admin 接的案子
 

Semelhante a Django Rest Framework, React, Redux Ecosystem

Practical catalyst
Practical catalystPractical catalyst
Practical catalystdwm042
 
An Introduction to Tornado
An Introduction to TornadoAn Introduction to Tornado
An Introduction to TornadoGavin Roy
 
Web Components v1
Web Components v1Web Components v1
Web Components v1Mike Wilcox
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2fishwarter
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2fishwarter
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2fishwarter
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2fishwarter
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineYared Ayalew
 
PHPConf-TW 2012 # Twig
PHPConf-TW 2012 # TwigPHPConf-TW 2012 # Twig
PHPConf-TW 2012 # TwigWake Liu
 
Building Modern Websites with ASP.NET by Rachel Appel
Building Modern Websites with ASP.NET by Rachel AppelBuilding Modern Websites with ASP.NET by Rachel Appel
Building Modern Websites with ASP.NET by Rachel Appel.NET Conf UY
 
Python Code Camp for Professionals 1/4
Python Code Camp for Professionals 1/4Python Code Camp for Professionals 1/4
Python Code Camp for Professionals 1/4DEVCON
 
Rails + Sencha = Netzke
Rails + Sencha = NetzkeRails + Sencha = Netzke
Rails + Sencha = Netzkebeffa
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVCAlive Kuo
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 

Semelhante a Django Rest Framework, React, Redux Ecosystem (20)

Django at the Disco
Django at the DiscoDjango at the Disco
Django at the Disco
 
Django at the Disco
Django at the DiscoDjango at the Disco
Django at the Disco
 
Django at the Disco
Django at the DiscoDjango at the Disco
Django at the Disco
 
Django at the Disco
Django at the DiscoDjango at the Disco
Django at the Disco
 
Practical catalyst
Practical catalystPractical catalyst
Practical catalyst
 
Django at the Disco
Django at the DiscoDjango at the Disco
Django at the Disco
 
An Introduction to Tornado
An Introduction to TornadoAn Introduction to Tornado
An Introduction to Tornado
 
Web Components v1
Web Components v1Web Components v1
Web Components v1
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App Engine
 
PHPConf-TW 2012 # Twig
PHPConf-TW 2012 # TwigPHPConf-TW 2012 # Twig
PHPConf-TW 2012 # Twig
 
Building Modern Websites with ASP.NET by Rachel Appel
Building Modern Websites with ASP.NET by Rachel AppelBuilding Modern Websites with ASP.NET by Rachel Appel
Building Modern Websites with ASP.NET by Rachel Appel
 
Python Code Camp for Professionals 1/4
Python Code Camp for Professionals 1/4Python Code Camp for Professionals 1/4
Python Code Camp for Professionals 1/4
 
Rails + Sencha = Netzke
Rails + Sencha = NetzkeRails + Sencha = Netzke
Rails + Sencha = Netzke
 
Flask – Python
Flask – PythonFlask – Python
Flask – Python
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 

Último

Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Neo4j
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 

Último (20)

Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 

Django Rest Framework, React, Redux Ecosystem

  • 1. Django Rest Framework and React and Redux, Oh My!
  • 2. I’m Eric Palakovich Carr. Co-Founder & Chief Architect at Previously:
  • 3. What this talk is not • A comprehensive tutorial • A deep dive into how these technologies works • You WILL need to go and learn this stuff on your own after this talk
  • 4.
  • 5.
  • 6.
  • 7.
  • 8. {% extends "base.html" %} {% load staticfiles %} {% block title %}Some Awesome Django Website{% endblock %} {% block extrahead %} <link rel="stylesheet" href="{% static "some.css" %}"/> <link rel="stylesheet" href="{% static "even_more.css" %}"/> {% endblock %} {% block body %} <!-- some content in Django template --> <div id="todolist"></div> <!-- more content in Django template --> {% endblock %}
  • 9.
  • 10. Javascript Ecosystem • We’ll be using NPM to manage your packages • We’ll be using webpack to handle bundling our assets. • We’ll be using scotch to burn away the memories of configuring the build system for our project.
  • 11. in a nutshell • The pip & cheeseshop / pypi of javascript • packages.json works like requirements.txt & setup.py • `npm init` in directory with packages.json generates node_modules. Kinda like a virtualenv directory. • packages.json also can act like your `manage.py` for your javascript code, but you populate it with custom commands.
  • 12. Building for Javascript • Start coding your project, using `npm install some-package — save` as you go. This creates and maintains your package.json. • Setup the config file for your build tool (webpack.config.js, gulpfile.js, Gruntfile, etc) • Add configs for Babel, minification, and other JS stuff • Add configs LESS, SASS, and other CSS stuff • Plus source mapping, tests, linters, sprite sheets, etc • Run your tool to generate bundles, having them save into your static directory for Django to pick up.
  • 13. {% extends "base.html" %} {% load staticfiles %} {% block title %}Some Awesome Django Website{% endblock %} {% block extrahead %} <link rel="stylesheet" href="{% static "bundle.css" %}"/> <link rel="stylesheet" href="{% static "some.css" %}"/> <link rel="stylesheet" href="{% static "even_more.css" %}"/> {% endblock %} {% block body %} <!-- some content in Django template --> <div id="todolist"></div> <script src="{% static "bundle.js" %}"></script> <!-- more content in Django template --> {% endblock %}
  • 14. {% extends "base.html" %} {% load staticfiles %} {% load render_bundle from webpack_loader %} {% block title %}Some Awesome Django Website{% endblock %} {% block extrahead %} <link rel="stylesheet" href="{% static "some.css" %}"/> <link rel="stylesheet" href="{% static "even_more.css" %}"/> {% endblock %} {% block body %} <!-- some content in Django template --> <div id="todolist"></div> {% render_bundle 'main' 'js' %} <!-- more content in Django template --> {% endblock %}
  • 15. DEMO
  • 16.
  • 17. // index.js import React from 'react'; import ReactDOM from 'react-dom'; import TodoHeader from './TodoHeader.jsx'; ReactDOM.render( ( <div className="todoWidget"> <TodoHeader listName="todos" /> </div> ), document.getElementById('todolist') );
  • 18.
  • 19. // index.js import React from 'react'; import ReactDOM from 'react-dom'; import TodoHeader from './TodoHeader.jsx'; ReactDOM.render( ( <div className="todoWidget"> <TodoHeader listName="todos" /> </div> ), document.getElementById('todolist') ); JSX
  • 20. // TodoHeader.jsx import React, { Component } from 'react'; export default class TodoHeader extends Component { render() { return ( <header className='todoHeadCmp'> <h1>{this.props.listName}</h1> </header> ); } }
  • 21. JSX // TodoHeader.jsx import React, { Component } from 'react'; export default class TodoHeader extends Component { render() { return ( <header className='todoHeadCmp'> <h1>{this.props.listName}</h1> </header> ); } }
  • 22. // TodoHeader.jsx import React, { Component } from 'react'; export default class TodoHeader extends Component { render() { return React.createElement( "header", {className: "todoHeadCmp"}, React.createElement( "h1", null, this.props.listName, ) ); } }
  • 23. export default class TodoTextInput extends Component { constructor(props, context) { super(props, context); this.state = { text: this.props.text || '' }; } handleSubmit(e) { const text = e.target.value.trim(); if (e.which === 13) { this.props.onSave(text); } } handleChange(e) { this.setState({ text: e.target.value }); } render() { return ( <input type='text' value={this.state.text} onChange={::this.handleChange} onKeyDown={::this.handleSubmit} /> ); } }
  • 24. React Component Lifecycle • componentWillMount • componentDidMount • componentWillReceiveProps • shouldComponentUpdate • componentWillUpdate • componentDidUpdate • componentWillUnmount
  • 25. Django Rest Framework • The Web browsable API is a huge usability win for your developers. • Authentication policies including packages for OAuth1a and OAuth2. • Serialization that supports both ORM and non-ORM data sources. • Customizable all the way down - just use regular function-based views if you don't need the more powerful features. • Extensive documentation, and great community support. • Used and trusted by large companies such as Mozilla and Eventbrite.
  • 26. Model->Serializer->ViewSet class Todo(models.Model): text = models.CharField(max_length=300) marked = models.BooleanField(default=False) class TodoSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Todo fields = ('id', 'text', 'marked') class TodoViewSet(viewsets.ModelViewSet): queryset = Todo.objects.all() serializer_class = TodoSerializer
  • 27. Demo
  • 28. Three Principles of Redux • Single source of truth • State is read-only • Changes are made with pure functions
  • 29. Redux State Tree / Store { visibilityFilter: 'SHOW_ALL', todos: [ { text: 'Consider using Redux', completed: true, }, { text: 'Keep all state in a single tree', completed: false } ] }
  • 30. Reducers { visibilityFilter: 'SHOW_ALL', todos: [ { text: 'Consider using Redux', completed: true, }, { text: 'Keep all state in a single tree', completed: false } ] }
  • 31. import * as types from '../constants/ActionTypes'; const initialState = []; export default function todos(state=initialState, action) { switch (action.type) { case types.ADD_TODO: return [...state, action.todo]; case types.DELETE_TODO: return state.filter(todo => todo.id !== action.id ); case types.EDIT_TODO: return state.map(todo => todo.id === action.todo.id ? action.todo : todo ); default: return state; } }
  • 32.
  • 33. store.dispatch({ type: 'ADD_TODO', todo: { text: "Check how much time is left", marked: false } }) store.dispatch({ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_COMPLETED' })
  • 34. Presentational Components • Are concerned with how things look. • Use props for displaying everything • Do not manage state at all • Don’t emit actions, but may take callbacks that do via props <MyComponent title=“No state, just props.” barLabels={["MD", "VA", "DE", "DC"]} barValues={[13.626332, 47.989636, 9.596008, 28.788024]} />
  • 35. Container Component • Are concerned with how things work. • Responsible for providing data to presentational components via props • Also responsible for handling state changes triggered inside a presentation component via callback prop. These state changes are often done via dispatching an action.
  • 36. class TodoApp extends Component { componentDidMount() { this.props.actions.getTodos(); } render() { const { todos, actions } = this.props; return ( <div> <Header addTodo={actions.addTodo} /> <MainSection todos={todos} actions={actions} /> </div> ); } } function mapState(state) { return { todos: state.todos }; } function mapDispatch(dispatch) { return { actions: bindActionCreators(TodoActions, dispatch) }; } export default connect(mapState, mapDispatch)(TodoApp);
  • 37. Wiring Redux to DRF • Python package “django-js-reverse" for getting your url routes in your javascript • NPM package “redux-promise”
  • 38. import * as types from '../constants/ActionTypes'; function deleteTodo(id) { return fetch(Urls.todo_detail(id), { method: 'delete', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'X-CSRFToken': getCookie('csrftoken') }, }).then(() => ({ type: types.DELETE_TODO, id: id })); } // In a component somewhere else store.dispatch(deleteTodo(this.props.todo.id))
  • 39. import * as types from '../constants/ActionTypes'; import * as api from ‘../path/to/MyApiLibrary'; function deleteTodo(id) { return api.deleteTodo(id).then(() => ({ type: types.DELETE_TODO, id: id })); } // In a component somewhere else store.dispatch(deleteTodo(this.props.todo.id))
  • 40. DEMO
  • 42. You need a build tool to create bundles. Webpack is nice for this.
  • 43. {% extends "base.html" %} {% load staticfiles %} {% block title %}Some Awesome Django Website{% endblock %} {% block extrahead %} <link rel="stylesheet" href="{% static "bundle.css" %}"/> <link rel="stylesheet" href="{% static "some.css" %}"/> <link rel="stylesheet" href="{% static "even_more.css" %}"/> {% endblock %} {% block body %} <!-- some content in Django template --> <div id="todolist"></div> <script src="{% static "bundle.js" %}"></script> <!-- more content in Django template --> {% endblock %}
  • 44. // index.js import React from 'react'; import ReactDOM from 'react-dom'; import TodoHeader from './TodoHeader.jsx'; ReactDOM.render( ( <div className="todoWidget"> <TodoHeader listName="todos" /> </div> ), document.getElementById('todolist') );
  • 45. // TodoHeader.jsx import React, { Component } from 'react'; export default class TodoHeader extends Component { render() { return ( <header className='todoHeadCmp'> <h1>{this.props.listName}</h1> </header> ); } }
  • 46. class Todo(models.Model): text = models.CharField(max_length=300) marked = models.BooleanField(default=False) class TodoSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Todo fields = ('id', 'text', 'marked') class TodoViewSet(viewsets.ModelViewSet): queryset = Todo.objects.all() serializer_class = TodoSerializer
  • 47. import * as types from '../constants/ActionTypes'; const initialState = []; export default function todos(state=initialState, action) { switch (action.type) { case types.ADD_TODO: return [...state, action.todo]; case types.DELETE_TODO: return state.filter(todo => todo.id !== action.id ); case types.EDIT_TODO: return state.map(todo => todo.id === action.todo.id ? action.todo : todo ); default: return state; } }
  • 48. import * as types from '../constants/ActionTypes'; function deleteTodo(id) { return fetch(Urls.todo_detail(id), { method: 'delete', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'X-CSRFToken': getCookie('csrftoken') }, }).then(() => ({ type: types.DELETE_TODO, id: id })); } // In a component somewhere else store.dispatch(deleteTodo(this.props.todo.id))
  • 49. Thanks! Eric Palakovich Carr @bigsassy on twitter and github example repo at https://github.com/bigsassy/drf-react-redux