CSC/ECE 517 Fall 2014/ch1a 8 os

From Expertiza_Wiki
Jump to navigation Jump to search

Django

Background

Architecture

Features

Object- Relational Mapper

Django has its own object relational mapper which eases database access. It facilitates writing of model classes directly in python. Model classes can be defined by sub-classing django.db.models.Model. Each attribute of this class corresponds to a database field. This makes it possible to use an automatically generated database access API.

from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

The database columns first_name and last_name are specified as class attributes and an id field is automatically added to the table.

Automatic admin interface

Generating admin sites for the staff to add,change or delete content is made easy by Django by automating the creation of admin interfaces for models. Creating an admin user is as easy as follows:

1. Create a user

$ python manage.py createsuperuser

2. Enter the username

Username: admin

3. Enter email address

Email address: admin@example.com

4. Final step is to setup a password as follows and the admin site gets created and is activated by default.

Password: **********
Password (again): *********
Superuser created successfully

Elegant URL Design

URLs can be designed using a module called URLconf. This module has simple python code in it which maps URL patterns to python functions(views) using regular expression based pattern matching. This mapping can reference other mappings. Since it is pure python code this mapping can also be gennerated dynamically.

How Django processes a request [1]

When a user requests a page from your Django-powered site, this is the algorithm the system follows to determine which Python code to execute:

  • Django determines the root URLconf module to use. Ordinarily, this is the value of the ROOT_URLCONF setting, but if the incoming HttpRequest object has an attribute called urlconf (set by middleware request processing), its value will be used in place of the ROOT_URLCONF setting.
  • Django loads that Python module and looks for the variable urlpatterns. This should be a Python list, in the format returned by the function django.conf.urls.patterns().
  • Django runs through each URL pattern, in order, and stops at the first one that matches the requested URL.
  • Once one of the regexes matches, Django imports and calls the given view, which is a simple Python function (or a class based view). The view gets passed the following arguments:
    • An instance of HttpRequest.
    • If the matched regular expression returned no named groups, then the matches from the regular expression are provided as positional arguments.
    • The keyword arguments are made up of any named groups matched by the regular expression, overridden by any arguments specified in the optional kwargs argument to django.conf.urls.url().
  • If no regex matches, or if an exception is raised during any point in this process, Django invokes an appropriate error-handling view.

Example:

Here’s a sample URLconf:

from django.conf.urls import patterns, url

from . import views

urlpatterns = patterns('',
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/(\d{4})/$', views.year_archive),
    url(r'^articles/(\d{4})/(\d{2})/$', views.month_archive),
    url(r'^articles/(\d{4})/(\d{2})/(\d+)/$', views.article_detail),
)

The Django template language

Django template system is aimed at achieveing a striking a balnce between power and ease of use. The system provides tags which function similar to normal programming constructs. There are tags like the if tag for conditions and the for tag for looping. A template is a text file which can be converted to HTML, CSV or any other text-based format. It has variables and tags. The variables get converted to values when the file is evaluated and the tags control the logic of the template. Django prefers a text-based template over a XML one so as to be able to use it for emails, Javascript and CSV etc. Also editing text-based templates is easier than modifying XML files. Django templates also support inheritance where in you can define a common skeleton template code in parent file and have blocks in it which can be overridden by children files. A comprehensive list of tags supported by the template language can be found here.

Cache framework

The power of Django lies in the way it performs in case of dynamic websites. In case of dynamic websites the server makes lot of complex calculations and database queries and performs some business logic for very request. This reduces the turn around time as the request not only affects the web server but also the application server and database server at times. For websites which handle heavy to very-heavy traffic loads this processing-overhead becomes a matter of concern. Caching is thus used to prevent repeating the same calculations again-and-again for every request. Caching preserves the result of a calculation the first time it is performed and returns the cached result for the subsequent requests unless the variables change and a new calculation is required. Following pseudocode explains the concept of caching for a dynamicaly generated web page

given a URL, try finding that page in the cache
if the page is in the cache:
    return the cached page
else:
    generate the page
    save the generated page in the cache (for next time)
    return the generated page

Django offers different levels of granularity for caching right from caching specific views and difficult to produce output to caching the entire web application. It also works well wit downstream caches such as Squid and browser based caches. The performance of your cache depends on whether you store it in database, in file system or directly on the memory. The fastest cache available to Django is the MemCached cache framework which is entirely a memory based cache. Memcached is used by sites like Facebook and Wikipedia to reduce database access and reduce turnaround delay.

Django can also store cache in the database. But this approach is advisable if the database server being used is fast and well indexed. Otherwise this method will hamper performance.

File based caching serialises and stores each cache as a separate file.

Local memory caching is the default option if no other option is specified in the settings file. It gives fast performance but is not memory efficient as cross-process caching is not possible. Hence this is a good option for development mode but not production mode.

Internationalization(i18n)

Internationalization is the process of delivering an application in the language and format suited to the audience. Django has support for translation of text, formatting of dates, timezone and numbers. Developers can specify which parts of the application should be sensitive to i18n and l11n and then uses them as hooks to localize web pages for particular class of audience. The information of language and region is provided by the browsers as part of the URL parameters.

The three steps for internationalizing your Django application are:

  • Embed translation strings in your Python code and templates.
  • Get translations for those strings, in whichever languages you want to support.
  • Activate the locale middleware in your Django settings.

1. Specify Translation Strings

Specifying translation string is marking a string to be translation sensitive in our python code. This can be done as follows

from django.utils.translation import ugettext as _

def my_view(request):
    output = _("Welcome to my site.")
    return HttpResponse(output)

In this example "Welcome to my site" is marked for translation.

2. Get translations for the strings

Once the strings have been marked for translation , it is necessary to obtain the translated version of those strings in whichever language is required. This can be achieved by maintaining message files for each language which maps the translation of each marked string in the particular language.

3. Activate the locale middleware

LocaleMiddleware allows language selection based on data from the request. To use LocaleMiddleware, add 'django.middleware.locale.LocaleMiddleware' to your MIDDLEWARE_CLASSES setting. Because middleware order matters, you should follow these guidelines:

  • Make sure it’s one of the first middlewares installed.
  • It should come after SessionMiddleware, because LocaleMiddleware makes use of session data.
  • If you use CacheMiddleware, put LocaleMiddleware after it.

For example, your MIDDLEWARE_CLASSES might look like this:

MIDDLEWARE_CLASSES = (
   'django.contrib.sessions.middleware.SessionMiddleware',
   'django.middleware.locale.LocaleMiddleware',
   'django.middleware.common.CommonMiddleware',
)

Comparison with other Web Frameworks

Django vs Ruby on Rails

Ruby is dynamic and reflective and focuses on empowering the programmer with flexibility and freedom of writing compact and concise code. The pilosophy of python is that everything needs to be declared explicitly by the programmer whereas philisophy of ruby is to allow the programmer to write code with implicit behaviour inherited from other components. Thus these behaviours also reflect in the design of rails and Django. Django requires that everything in the project be explicitly configured whereas rails believes in "convention over configuration". In rails if you adhere to specific conventions then rails does the configuration for you. All components such as models,controllers, stylesheets are located in predefined directory structures. You can drop your custom files into these directories and rails will pick them up if you follow standard naming convention. Rails offers scaffolding script which allows us to generate controllers from command line while django does not provide any such feature. Django provides authentication and authorization support out-of-the-box while rails does not provide any such support out-of-the-box. Django strives towards performance whereas rails focusse on programmer productivity as its prime objective.

Django vs Web2Py

In Django you need to explicitly import all the functions you use. web2py is similarto rails and imports all the used functions automatically.

In Django you need to do the following:

from django.http import HttpResponse
def index(request):
 return HttpResponse("Hello World”)

The following web2py code does the same job:

def index(): 
 return "Hello World"

IN both Django and web2py the GET/POST requests contain all the parameters unlike in rails. In Django you can use .GET or .POST and in web2py you can use .get_vars and .post_vars to obtain the parameters.

In Django un like rails we can ru multiple applications at one time as the url includes the name of the app. But we need to edit url.py for mapping urls to their specific actions. There are no defaults and you need to have one entry in url.py for every action. Dispatching in web2py is similar to that in rails but the URL needs to specify the name of the app by default. This allows it to run multiple apps simultaneously without using routes.

In Django models are defined at single place. Django does not do migrations and for many-to-many relations it creates an intermediate link table. web2py has a functionality similar to rails and many-to-many relations are implied by reference fields.

References