CSC/ECE 517 Fall 2014/ch1a 8 os

From Expertiza_Wiki
Jump to navigation Jump to search

Writeup Page

Django<ref>https://www.djangoproject.com/ Django Homepage</ref>

Django is a free and open source web application framework, written in Python, which follows the model–view–controller architectural pattern. It is maintained by the Django Software Foundation (DSF), an independent non-profit organization established<ref>http://en.wikipedia.org/wiki/Django_(web_framework)</ref>.

Django's primary goal is to ease the creation of complex, database-driven websites. Django emphasizes reusability and "pluggability" of components, rapid development, and the principle of don't repeat yourself (DRY). Python is used throughout, even for settings, files, and data models. Django also provides an optional administrative create, read, update and delete interface that is generated dynamically through introspection and configured via admin models.

Some well known sites that use Django include Pinterest, Instagram, Mozilla, The Washington Times, Disqus and OpenStack.

Background <ref>http://www.djangobook.com/en/2.0/chapter01.html</ref>

In summer 2005, after having developed this framework to a point where it was efficiently powering most of World Online’s sites, the team, which now included Jacob Kaplan-Moss, decided to release the framework as open source software. They released it in July 2005 and named it Django, after the jazz guitarist Django Reinhardt.

Now, several years later, Django is a well-established open source project with tens of thousands of users and contributors spread across the planet. Two of the original World Online developers (the “Benevolent Dictators for Life,” Adrian and Jacob) still provide central guidance for the framework’s growth, but it’s much more of a collaborative team effort.

This history is relevant because it helps explain two key things. The first is Django’s sweet spot because Django was born in a news environment, it offers several features that are particularly well suited for “content” sites – sites like Amazon.com, craigslist.org, and washingtonpost.com that offer dynamic, database-driven information. Don’t let that turn you off, though – although Django is particularly good for developing those sorts of sites, that doesn’t preclude it from being an effective tool for building any sort of dynamic Web site.

The second matter to note is how Django’s origins have shaped the culture of its open source community. Since Django was extracted from real-world code, rather than being an academic exercise or commercial product, it is acutely focused on solving Web development problems that Django’s developers themselves have faced – and continue to face. As a result, Django itself is actively improved on an almost daily basis. The framework’s maintainers have a vested interest in making sure Django saves developers time, produces applications that are easy to maintain and performs well under load. If nothing else, the developers are motivated by their own selfish desires to save themselves time and enjoy their jobs.

Architecture <ref>http://lukeplant.me.uk/blog/posts/mvc-is-not-a-helpful-analogy-for-django/</ref>

Django’s Model-View-Template (MVT) architecture is a little different from Model-View-Controller (MVC) architecture. MVC is primarily about managing the changes in state so that everything is kept in sync. Model, View and Controller are all things that exist at the same time in memory (possibly running in different threads or processes), for extended periods, with their own state, and have to interact with each other.

On the contrary, in MVT, there is no state. There is only data. For the purposes of most HTTP requests (GET requests), the data in the database is treated as an immutable data input, not state. It could be said that the name ‘view’ is misleading, since it implies reading, not writing, i.e. GET requests not POST requests. A better name might be ‘handler’, because it handles an HTTP request, and that is the terminology used by most Django REST frameworks.

In HTTP, stateful interactions can be built up by modifying data on the server, and modifying data on the client (cookies). But these modifications are outside the scope of a single page view. The browser holds one half of the state — the state of the current page, and cookies — and the session database holds the other half.

But when it comes to responding to an HTTP request, Django’s MVT has a complete lack of state. Many web pages are essentially pure functions of the inputs — an HTTP request and the data in the database — so it is clear that MVT is not intrinsically about state.

Of course, there is data modification. POST requests are about that. But these do not result in views being ‘notified’. Classic web apps handle state by side-stepping it completely. If a user know that the ‘state’ of the system has changed (i.e. new data in the database), the user presses Refresh, which:

  • Throws away all the state (i.e. the current state of the browser), with the exception of the pieces of state that identify what the user was looking at - the URL, and the site’s cookies.
  • Causes a brand new HTTP request asking for the document. The server responds completely from scratch: it doesn’t notify the view function or the template, it runs over from the beginning.

So, if anything changed, the approach is cancel everything, start again from the beginning.

And for the actual handling of POST requests within Django, you have a similar approach. Once the data has been updated (typically, a SQL INSERT or UPDATE), you send back an HTTP redirect to do a GET — something changed, let’s start again from the beginning. This is why Django’s ORM does not have an identity mapper. The model for handling state is to ignore it altogether, and just start again whenever you know that something has changed.

This is exactly the opposite of the way classic MVC apps work (including client-side, Javascript MVC frameworks) — they are all about avoiding starting again, and having live systems that can be informed about updates and keep everything in sync, by sending message between them.

There is a second aspect to MVC, which is separation of concerns. If you think of MVC as meaning separation of code that stores data, code that displays data, and code that handles requests for data to be changed or displayed, then Django does indeed fit that pattern.<ref>http://www.slideshare.net/fishwarter/the-django-web-application-framework-2-1221388 Django Architecture</ref><ref>http://jeffcroft.com/blog/2007/jan/11/django-and-mtv/ Models, Views and Templates</ref>

Django Architecture
Django Architecutre - MVT

Model

The model acts as a definition of some stored data. In a web application, this data is usually stored in a relational database, but it doesn’t have to be — it could be in an XML file, an LDAP schema, and so on. In Django, a model is a Python class that outlines the variables and methods for a particular type of data.

View

In most typical Django applications, the purpose of the view is to determine what data is to be displayed, retrieve it from the database, and pass it off to the template. Views are Python functions. Typically, you will have one view for each type of page within your site.

In most Django views, the programmer takes advantage of Django’s built-in object-relational mapping API to retrieve some set of information from the database. The ORM allows one to write Python code instead of SQL for these functions (although you can still drop down a level and write SQL directly, if you prefer). Views may also perform other kinds of tasks besides database interaction — tasks like sending e-mail messages, authenticating against some external service, and validating form input are all common.

The most common end point for a view function is to hand off a context to a template for rendering. A context is simply the variables that are available to the template. It’s important to understand that the view has no bearing over how the data is presented — only which data is presented (this is where Django varies from some other MVC frameworks).

Template

In a typical Django web application, the template is simply an HTML page with a few extra goodies. Django’s template language can actually create any sort of text file (XML, email, CSS, Javascript, CSV, etc.) The template receives a context from the view . Its job, then, is to organize those context variables (using any of their attributes or methods from the model) into an HTML page that will be displayed by the browser.

Django’s template language is designed to be accessible by designers who aren’t necessarily programmers. It offers several basic tags, as well as a large selection of built-in filters for modifying the output of variables and methods. It contains basic programming constructs, such as if statements and for loops, which are often needed for presentation logic. But, unlike some other template languages, you can not arbitrarily put Python code into a template. The language is intentionally limited so as to encourage you to properly separate your presentation logic from your business logic. Seasoned programmers sometimes find this limiting.

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 <ref>http://www.pythoncentral.io/python-django-vs-ruby-on-rails/</ref>

Ruby is dynamic and reflective and focuses on empowering the programmer with flexibility and freedom of writing compact and concise code. The philosophy of python is that everything needs to be declared explicitly by the programmer whereas philosophy 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 focuses on programmer productivity as its prime objective. Following table describes the differences in a neat way.

Django vs Ruby on Rails
Feature Django Rails
Project Structure Everything in the project needs to be explicitly configured. Has some implicit understanding of project structure.
Philosophy It follows "configuration over convention" It believes in "convention over configuration"
Project components structure You need to let django know where the components like css etc. are located All components are located in predefined directory structures.
Scaffolding Does not offer any scaffolding kind of mechanism Offers scaffolding which help generate controllers and views from command line.
Authentication/Authorization Provides authentication and authorization support out-of-the-box Does not provide any such support.
Goal Strives towards performance Focuses on increased programmer productivity.

Django vs Web2Py <ref>http://www.web2py.com/examples/static/web2py_vs_others.pdf</ref>

In Django you need to explicitly import all the functions you use. web2py is similar to 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 unlike rails we can run 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

<references/>