over 2 years ago

When writing a Django project, it happens often that mulitple apps will be included. Let me use an example:

Project
    - Account
    - Journal

In this example, I created a Django project that contains two apps. The Account app handles user registration and login. The Journal app allows users to write journals and save it to the database. Here is the what the urls look like:

#ROOT_URLCONF


urlpatterns = [
    url(r'^account/', include('Account.urls', namespace='account')),
    url(r'^journal/', include('Journal.urls', namespace='journal')), #This namespace name is used later, so just remember we have given everything under journal/ a name

]

This above file is what the ROOT_URLCONF points to. Inside the Note app, the urls look like this:

urlpatterns = [
    url(r'^(?P<id>[0-9]{4})/$', FormView.as_view(), name = 'detail'),
]

So each journal has a 4 digit id. When a journal is access, it's url may look like this: www.mynote.com/note/1231/

Let's say user John bookmarked a journal written by another person. He wants to comment on it. When John tries to access that journal www.mynote.com/note/1231/, he is redirected to the login page. In the login page's view handler, a redirect should be made to Journal ID 1231 once authentication is passed:

def view_handler(request):
    # authentication passed

    return redirect(reverse('detail', kwargs={'id', '1231'}))

The reverse(...) statement is not going to work in this case. Because the view_handler belongs to the Account app. It does not know about the urls inside the Journal app. To be able to redirect to the detail page of the Journal app:

reverse('journal:detail', kwargs={'id', '1231'})

So the format for reversing urls that belong to other apps is:

reverse('namespace:name', args, kwargs)
 
over 2 years ago

There are some pitfalls when you need to create and login users manually in Django. Let's create a user first:

def view_handler(request):
    username = request.POST.get('username', None)
    password = request.POST.get('username', None)

Note that request.POST.get('username', None) should be used instead of request.POST['username']. If the later is used, you will get this error:

MultiValueDictKeyError

Once the username and password are extracted, let's create the user

User.objects.create(username=username, password=password, email=email) # DON'T DO THIS

The above code is wrong. Because when create is used instead of create_user, the user's password is not hashed. You will see the user's password is stored in clear text in the database, which is not the right thing to do.

So you should use the following instead:

User.objects.create_user(username=username, password=password, email=None)

What if you want to test if the user you are about to create has already existed:

user, created = User.objects.get_or_create(username=username, email=None)
if created:
    user.set_password(password) # This line will hash the password

    user.save() #DO NOT FORGET THIS LINE

get_or_create will get the existing user or create a new one. Two values are returned, an user object and a boolean flag created indicating whether if the user created is a new one (i.e. created = True) or an existing one (i.e. created = False)

It is import to not forget including user.save() in the end. Because set_password does NOT save the password to the database.

Login

Now a user has been created successfully, the next step is to login.

user = authenticate(username=email, password=password)
login(request, user)

authenticate() only sets user.backend to whatever authentication backend Django uses. So the code above is equivlent to:

user.backend = 'django.contrib.auth.backends.ModelBackend'
login(request, user)

Django's documentation recommends the first way of doing it. However, there is an use case for the second approach. When you want to login an user without a password:

username = self.request.GET.get('username')
user = User.objects.get(username=username)
user.backend = 'django.contrib.auth.backends.ModelBackend'
login(request, user)

The is used when security isn't an issue but you still want to distinguish between who's who on your site.

So to sum up the code above, here is the view_handler that manually create and login an user:

def view_handler(request, *args, **kwargs):
    email = request.POST.get('email', None)
    password = request.POST.get('password', None)
    if email and password:
        user, created = User.objects.get_or_create(username=email,
                                                   email=email)
        if created:
            user.set_password(password)
            user.save()

        user = authenticate(username=email, password=password)
        login(request, user)
        return HttpResponseRedirect('where_ever_should_be_redirect_to')
    else:
        # return error or redirect to login page again
 
over 2 years ago

Saw this example on MDN:

var str = 'rawr';
var searchFor = 'a';

// this is alternative way of typing if (-1*str.indexOf('a') <= -1)

if (~str.indexOf(searchFor)) {
  // searchFor is in the string

} else {
  // searchFor is not in the string

}

According to the documentation,

Bitwise NOTing any number x yields -(x + 1). For example, ~5 yields -6.

So if a character exists within a string, indexOf will return the first occurance of that character's index which will either be an 0 or any positive nubmer.

Thus, the tilde operator will turn them into:

~0 === -1 
~1 === -2
~2 === -3
...

Any none zero number is considered a true in JS, so:

1 == true
-1 == true

Thus, if str.indexOf() returns any number other than -1, ~str.indexOf() equals to a negative number, which will be considered True.

In the case of -1 is returns (i.e. the character does not exist in the string):

~(-1) === 0

0 == false

Thus, the else branch is executed.

 
over 2 years ago

To enable token based authentication using DRF, the following steps need to be done (I am using Django 1.8.5 and DRF 3.2.4):

  1. Do the following things BEFORE you create the superuser. Otherwise, the superuser does not get his/her token created.

  2. Go to settings.py and add the following:

INSTALLED_APPS = (
    'rest_framework',
    'rest_framework.authtoken',
    'myapp',
)

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    )
}
  1. Add the following code in myapp's models.py:
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
from django.conf import settings

# This code is triggered whenever a new user has been created and saved to the database

@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)

Alternatively, if you want to be more explicit, create a file named signals.py under myapp project. Put the code above in it, then in init.py, write import signals

  1. Open up a console window, navigate to your project dir, and enter the following command:
python manage.py migrate
python manage.py makemigrations

Take a look in your database, a table named authtoken_token should be created with the following fields: key (this is the token value), created (the datetime it was created), user_id (a foreign key that references the auth_user table's id column)

  1. create a superuser with python manage.py createsuperuser. Now, take a look at the authtoken_token table in your DB with select * from authtoken_token;, you should see a new entry has been added.

  2. Using curl or a much simpler alternative httpie to test access to your api, I am using httpie:

http GET 127.0.0.1:8000/whatever 'Authorization: Token your_token_value'

That's it. From now on, for any API access, you need to include the following value in the HTTP header (pay attention to the whitespaces):

Authorization: Token your_token_value
  1. (Optional) DRF also provides the ability to return a user's token if you supply the username and password. All you have to do is to include the following in urls.py:
from rest_framework.authtoken import views

urlpatterns = [
    ...
    url(r'^api-token-auth/', views.obtain_auth_token),
]

Using httpie to verify:

http POST 127.0.0.1:8000/api-token-auth/ username='admin' password='whatever'

In the return body, you should see this:

{
    "token": "blah_blah_blah"
}

Improvements

DRF's token implementation lacks a few important features:

  • Tokens do not rotate
  • Tokens do not expire
  • The same token is shared among all the clients (PC browsers, smartphones, tablets, etc.)

The Django Oauth Toolkit should be considered as a step up.

 
over 2 years ago

While learning react, many tutorials have recommend to use webpack for building react apps. I created a very simple react app on Github to demonstrate the concept of webpack.

What does Webpack do? Why do I need it when using React?

React encourages you to write reusable UI components. Let's say you write a date picker. It comes with its own CSS style sheet and a background image. To reuse this component elsewhere, you need to pack the source code along with all the resources into one package for others to download.

Webpack does just that:

fonts + images + CSS + source code => bundle.js

How does it work?

Download this example I wrote and take a look at the index.js file. On the third line of index.js you will see:

var Style = require('./style.css');   // the './' in front of style.css is important, if missing, require will go into node_modules to look for it which is not what we want

You might think this line is broken because how can you import a .css into a .js file. While, it works because of Webpack. Open up webpack.config.js and take a look at this part (starting at line 18):

{
    test: /\.css$/,  // a regex to match all .css files

    loader: 'style-loader!css-loader' //css-loader acts first to interpret require('.css') and read the content of the css file. Then, it passes the content to style-loader which insert the css as <style>content</style> into the header section of a HTML file. The ! mark is used to chain loaders. The order of the loader execution is from right to left.

}

Webpack uses loaders to deal with different file formats during the packing stage. In this case, css-loader and style loader are used to deal with .css file type. If you write in LESS or SASS, there are corresponding loaders to deal with those.

There are two ways to enable loaders, the most common way is to specify them in the webpack.config.js file:

{
    test: /\.png$/, // use regex to match all the png files

    loader: 'url-loader?limit=300&name=[name].[ext]' // use url-loader to deal with png files. You can pass parameters to a any loader using 'whatever-loader'?param=value' format

}

All .png files will be dealt with the url-loader. What the url-loader does is to turn a file into data URI. In this case, the file small_img.png is turned into:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAGCAYAAADOic7aAAAAH0lEQVQY02M4cODAfyhmgGKy+AzUNIgqmKoGDa4wAgBEaBrozyRdGQAAAABJRU5ErkJggg==

The limit=300 part means if the file is less than 300 bytes, then turn it into data URI.

Another way to enable loader is shown on line 11 in index.js:

<img src={require('file-loader?name=[name].[ext]!./large_img.jpg')}></img>

If you specify the loader this way, then it would only affect this particular jpg file rather than all the jpg files in your project.

The file-loader reads a file and return the file in the following format:

MD5_hash_of_the_file_content.extension

We don't want to reference a file with a hash name, instead we would like to reference it using the file's original name and extension. name=[name].[ext] does just that.

Once all the loaders are being configured, run the webpack command to transform the assets into data URIs or plain file names. Then, you can open up index.html in the browser to see the result.

Conclusion

I hope this post provides a general overview of what Webpack does and how it fits into the big picture of react development.

 
over 2 years ago

Julien Phalip gave a great talk at DjangoCon 2015, he introduced three ways to hydrate (i.e. load initial data into React component on first page load) React app with data, I am going to quote him directly from the slides and add my own comments.

  1. Conventional Method: Client fetches data via Ajax after initial page load.

    Load the data via ajax after initial page load.

  2. Less conventional method: Server serializes data as global Javascript variable in the inital HTML payload (see Instagram).

    Let the server load the data first, then put it into a global Javascript variable which is embed inside the returned HTML page.

    In the linked Github project (which is a Django project), the server fetches from the database to get all of the data. Then, it converts the data from Python object to json format and embed the data in the returned HTML page.

  3. Server side rendering: Let the server render the output HTML with data and send it to the client.

    This one is a little bit involved. Django would pass the data from DB along with the React component to python-react for rendering.

    python-react is a piece of code that runs on a simple Node HTTP server and what it does is receiving the react component along with data via a POST request and returns the rendered HTML back. (The pyton-react server runs on the same server as your Django project.)

So which method to use then?

We can use the number of round trips and the rendering speed as metrics for the judgement.

Method 1

Round trips: The inital page request is one round trip, and the following ajax request is another one. So two round trips.

Rendering time: Server rendering is usually faster then client rendering, but if the amount of data gets rendered is not a lot then this time can be considered negligible. In this case, the rednering happens on the client side. Let's assume the amount of data need to be rendered is small and doesn't impact the user experience, then it is negligible.

Method 2

Round trips: Only one round trip

Rendering time: Negligible as aforementioned.

Method 3

Round trips: Only one round trip

Rendering time: If it is negligible on the client side then it is probably negligible on the server side.

It seems that Method 2 & 3 are equally fast. The differences between them are:

  • Method 2 renders on the client side and Method 3 renders on the server side.
  • Method 3 requires extra setup during development and deployment. Also, the more moving pieces there are, the more likely it breaks and takes longer to debug.

Conclusion

Without hard data to prove, here is just my speculation: Use Method 2 most of the time and only Method 3 if you think rendering on the client side is going to be slow and impact the user experience.

 
over 2 years ago

A lot of react projects hosted on github use ES6/7 syntax. I had a lot of headaches when reading them since I am not familiar with the new syntax. I decided to learn it by converting a simple react project written in ES5 to ES6. I documented the transitions I made while conveting it to ES6/7.

Importing React

ES5

var React = require('react');
var ReactPropTypes = React.PropTypes;

ES6

import React, {Component, PropTypes} from 'react';

To understand why there is no '{}' around React, let's take a look at react's source code:

var React = {
  ...
  Component: ReactComponent,   // both Component and PropTypes are like 'plain exports' in ES6

  PropTypes: ReactPropTypes,
  ...
}

module.exports = React;  /* this line is like the default export in ES6 */

In ES6, when importing a default export, there is no need to wrap it around {}, everything else has to be inside {}

Creating React Component and Exporting it

ES5

var Header = React.createClass({
    render: function() {
        return (
            <header>
                <h1>This is the header section</h1>
            </header>
        );
    }
});

module.exports = Header;

ES6

export default class Header extends Component {
    render() {
        return (
            <header>
                <h1>This is the header section</h1>
            </header>
        );
    }
}

You can use 'export default' if you don't care how the Header component will be named when it is imported, or use 'export' instead if you want to enforce its name.

PropTypes

ES5

var React = require('react');
var ReactPropTypes = React.PropTypes;

var Header = React.createClass({
    propTypes: {
      title: ReactPropTypes.string.isRequired
    }
});

ES6

import React, {Component, PropTypes} from 'react';

export default class Header extends Component {
    render() {
        return (
            <header>
                <h1>This is the header section</h1>
            </header>
        );
    }
}

//Note that the propTypes has to be defined outside of the class definition

Header.propTypes = {
    title: PropTypes.string.isRequired
}

The ES6 syntax looks weird because the propTypes section is outside of the class definition. This is due to the fact that only methods can be defined inside a class in ES6. If you want to define properties, they have to be outside of the class.

To avoid this issue, I prefer to use ES7 Property Initialiazers:

ES7

import React, {Component, PropTypes} from 'react';

export default class Header extends Component {

    // brings the propTypes inside the class definition

    // Note that propTypes belongs to the class, and thus it is static

    // non-static properties (instance properties) is shown in the next section

    static propTypes = {
        title: PropTypes.string.isRequired
    }

    render() {
        return (
            <header>
                <h1>This is the header section</h1>
            </header>
        );
    }
}

getInitialState

ES5

var Header = React.createClass({
    getInitialState: function() {
        return {
            title: this.props.title
        };
    },
});

ES6

export default class Header extends Component {
    constructor(props) {    /* Note props is passed into the constructor in order to be used */
        super(props);
        this.state = {
            title: props.title
        };
    }
}

To furthur simplify this code using ES7's property initializer:

ES7

export default class Header extends Component {
    // instance property

    state = {
        title: this.props.title
    };
    
    // followed by constructor...

}

Invoking Methods

Let's borrow an example from the offical react tutorial:

ES5

var Header = React.createClass({
    handleClick: function(event) {
        this.setState({liked: !this.state.liked});  // Note here that **this** is automatically bind to the componenet itself

    }
});

However in ES6, the React team decided to not automatically bind this to the component. So to rewrite the code above in ES6, we need to bind the handleClick function to the component inside the constructor:

ES6

export default class Header extends Component {
    constructor() { 
        super();
        this.handleClick = this.handleClick.bind(this);
    }
    
    handleClick(event) {
        this.setState({liked: !this.state.liked});  
    }
}

The React blog also suggested to use ES7 property initializers to make it even simpler:

ES7

export default class Header extends Component {
    handleClick = (event) => {
        this.setState({liked: !this.state.liked});  
    }
}

This code needs some explanation. The handleClick = ... part is ES7 property initializer stuff. The (event) => {} is ES6 fat arrow function which preserves this context when it is called.

There are quite a few ways to accomplish this using es6/7 but this is the simpliest way recommended by the React team.

Conclusion

These are the conversions needed to convert your code from ES5 to ES6/7. The new syntax reduces the amount of code and makes it look better IMO. It is definitely a good time to start learning the new syntax and using it in React.

 
over 2 years ago

UPDATE: A video tutorial of this post has been created by webucator. They also offer a set of Python online training classes.

Thanks to this SO post, here are the ways to shallow and deep copy lists in Python:

Shallow Copy (from fastest to slowest)

new_list = old_list[:]
new_list = [] 
new_list.extend(old_list)
new_list = list(old_list)
import copy

new_list = copy.copy(old_list)
new_list = [i for i in old_list]
new_list = []

for i in old_list:
    new_list.append(i)

Deepcopy (the slowest)

import copy

new_list = copy.deepcopy(old_list)
 
over 2 years ago

A few weeks ago, I wrote a blog on how to setup ST3 for React dev. Since then, I learned more about react development, I started to use eslint. Jslint is great but it does not support JSX. We need a linter that can be integrated with ST3 and show live linting result while coding. This is where eslint comes in.

Install eslint

You can install it either globally or locally. I installed it globally:

npm install -g eslint eslint-plugin-react

The only hiccup to start using eslint is its stunning numbers of configurable options available. I have included a .eslintrc file to get your started(Just copy and paste this code your your .eslintrc file). The majority of this file is based on this example and this project. I added/modified the following:

  • Enable JSX linting via eslint-plugin-react
  • Enable ES6 syntax
  • Enable ES6 module import and export
  • Use single quote instead of double quote around strings (you can always change this by replacing "quotes": [1, "single"] with "quotes": [1, "double"]. Just search for the quotes keyword.

A note about eslint's syntax, eslint use 0, 1 and 2 to represent:

  • 0 - disable the rule
  • 1 - display warning when a rule is violated
  • 2 - display error when a rule is violated

You can always look up a eslint setting here.

Enable eslint in Sublime Text 3 (ST3)

  1. Make sure SublimeLinter3 is installed first.
  2. Install SublimeLinter-eslint
  3. Make sure you have a .eslintrc file in your current project's root folder. Open up the project folder in sublime and wait for a few seconds for eslinter to kick in.

[Optional] Disable jshint in ST3

If you also have sublime-jshint installed, you want to disable it otherwise both jshint and eslint will lint your project. To do this, inside ST3, save your project by (Project -> Save project as ...). This will create a .sublime-project file, inside this file, put the following config inside:

{

    "SublimeLinter":{
        "linters":{
            "eslint":{
                "excludes":[
                    "dist/*",
                    "node_modules/*"
                ]
            },
            "jshint":{
                "@disable":true
            }
        }
    }
}

This config tells SublimeLinter to:

  1. disable jshint
  2. tell eslint to ignore your dist and node_modules folder

Note

Whenever you modify the .eslintrc file, it will NOT take effect unless your restart ST3. Also, when ST3 is opened, it will not respond to any user input for a few seconds because eslint is working in the background linting your files.

 
over 2 years ago

While setting the timezone for a Django server, I made a stupid mistake in the settings.py file:

TIME_ZONE = 'Asia/Shanghai'
USE_TZ = True

There is nothing wrong with the parameter names and syntax. After loading up the server, Django keeps using UTC time despite the fact that I have set TIME_ZONE = 'Asia/Shanghai'

The problem is caused by placing TIME_ZONE above USE_TZ. The order of these two lines matter here. The right way to do is:

USE_TZ = True
TIME_ZONE = 'Asia/Shanghai'