A project in django is analogous to a website. Once we have a project ready,
we can host it using any wsgi supported server. More on deploying a django project
later.

django-admin.py is a project utility that ships with django. In addition to the startproject
subcommand, it also includes a lot of helper subcommands that can be useful while maintaining a django
project.

Note

To get a full listing of available subcommands in django-admin.py, use:

django-admin.py--help

To get help on each subcommand, use:

django-admin.py help <subcommand>

For example, here’s the result of django-admin.pyhelpstartproject:

Creates a Django project directory structure for the given project name in the current directory.

Lets create a project called djen_project:

django-admin.py startproject djen_project

We can see that the subcommand creates a folder called djen_project in the working directory with the following files:

__init__.pymanage.pysettings.pyurls.py

__init__.py is an empty file required to recognize this project as a python module.

manage.py is a script that is similar to django-admin.py which allows you to manage this project. It has
subcommands to start a development server, interact with database, backup/restore data etc.

Note

manage.py also has –help switch and help with each subcommand similar to django-admin.py

You can quickly checkout the development server at this point by running:

settings.py is a list of project wide settings with sane default values. You will need to edit this often when
installing new django applications, deployment etc.

You can change the DATABASES settings at this point to make sure your app can be sync’ed later. The easiest
settings would look like:

DATABASES={'default':{'ENGINE':'django.db.backends.sqlite3',# Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.'NAME':'cd.db',# Or path to database file if using sqlite3.'USER':'',# Not used with sqlite3.'PASSWORD':'',# Not used with sqlite3.'HOST':'',# Set to empty string for localhost. Not used with sqlite3.'PORT':'',# Set to empty string for default. Not used with sqlite3.}}

or for a mysql:

DATABASES={'default':{'ENGINE':'django.db.backends.mysql',# Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.'NAME':'djen_database',# Or path to database file if using sqlite3.'USER':'root',# Not used with sqlite3.'PASSWORD':'****',# Not used with sqlite3.'HOST':'',# Set to empty string for localhost. Not used with sqlite3.'PORT':'',# Set to empty string for default. Not used with sqlite3.}}

We will be using mysql database for examples in this book. Of course, you are free to change
the settings to any other database you like. Just make sure the database exists.

Note

To verify your database settings run:

python manage.py validate

Django will validate your settings and show you errors, if any. If you get this error:

_mysql_exceptions.OperationalError: (1049, "Unknown database...

make sure the database given in the settings exists.

Note

It is advised to have a local_settings.py file with exclusively server specific and sensitive settings like database username/password,
API keys or Secret Key etc and have settings.py import all these values.

To do this, you would create local_settings.py and include fromlocal_settingsimport* at the bottom of settings.py

urls.py is a ‘table of contents’ of our project (or website). It includes a list of the paths that are to be processed
and responded to.

You are encouraged to go through settings.py and urls.py once to get an understanding of how settings and urls are defined.

Now that we have setup and understood the structure of our project, we can start our application.

To start an application, cd into the project directory and use

manage.py startapp cd_library

This will create a folder called cd_library with the following files:

__init__.pymodels.pytests.pyviews.py

__init__.py is again the file that allows this app to be considered a python module.

models.py will hold the Models of our application. A model is an object of our interest which we want to
save to the database. If you are familiar with Model-View-Controller(MVC) architecture, you know what models are.
If no, don’t worry, we will see and use them in our application.

views.py has all the ‘action’ of our website. This is similar to the Controller of MVC architecture. Each ‘view’ function
takes a request object and returns a HttpResponse object.

Note

It is recommended to have another urls.py (like the one in project) in the app and include them in the project urls.
This reduces the clutter in the project urls and provides a namespace kind of resolution between urls. Also, it makes
it easier to redistribute the app to other projects. As you would expect, reusable apps will depend on the project as
little as possible.

Let us create our models first:

Open models.py and define our CD model which will hold all information related to a CD. You can see that models.py has:

Each CharField requires a max_length argument which specifies the maximum length of the characters that
the field can hold.

A TextField can contain any number of characters and is suitable for fields such as description, summary, content etc.

To make the description field optional, we pass the null and blank arguments as True

DateField holds a date. If you need to store the time too, use DateTimeField instead.

The genre field should be restricted to a group of values and that can be accomplished by passing an iterable of 2-tuples
for the value and representation as the choices argument of the CharField.

The __unicode__ property of the model defines it’s string representation which will be used in the Admin interface, shell etc.

So far, we have defined the CD model, now we need to get it rolling in django:

First, let django know that cd_library is to be used in the project. To do this, edit the project settings.py and add:

'cd_library'

to the INSTALLED_APPS list so that your settings.py looks like this:

INSTALLED_APPS=('django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.sites','django.contrib.messages',# Uncomment the next line to enable the admin:# 'django.contrib.admin','cd_library',)

Note

After modifying INSTALLED_APPS, it’s always a good idea to run syncdb:

python manage.py syncdb

This lets django keep the database and your project in sync. Since we have added an app,
django will create that app’s tables in the database. If an app is removed from the above
list, django will ask you whether to remove the ‘stale’ tables.

Also, make sure you have DATABASES settings correctly pointed to the database before syncing.

Well, now that django knows about our app, let us add it to the Admin interface.

A little bit about the admin interface first:

The admin interface is itself a django app.

It is a contrib app, which means it is a community contributed app

It is flexible enough to accommodate any other app’s models and have admin actions for them.

Since the admin is an app, it needs to be added to INSTALLED_APPS as well. You would have noticed this in the commented lines above.

So just go ahead and uncomment the django.contrib.admin line in settings.py under INSTALLED_APPS. Don’t forget to run syncdb.

Now we have similar instructions in urls.py to uncomment a few lines to enable the admin. This will enable the urls beginning with
admin to be mapped to the admin app’s urls. Note that the admin app uses a urls.py to keep its urls separate from the project
(as discussed in the note above).

Just to confirm it, you can open http://127.0.0.1:8000/admin/ in your browser. You should see ‘Site Administration’ and actions for ‘Auth’
and ‘Sites’ which are enabled by default.

Now to enable our app’s models:

Go to the app’s directory i.e. cd_library and create a file called admin.py and add the following lines:

If you refresh the admin page, you can see the ‘Cd_library’ header and ‘Cds’ under it. Yes this is our app’s model
and we can add/edit/delete any instances of our CD model through the admin interface. Try adding a few entries using the
Add action. You can edit entries using the Change action which will take you to the change list page. Try editing and
deleting entries.

Did you notice?:

Django uses the models __unicode__ property to display the CD in the change list

We have configured the database django uses in ‘DATABASES’ attribute of settings.py. Notice that
you can enter multiple database settings and use them by providing the --database switch
to manage.py subcommands.

To go to the database shell and view the database, use:

python manage.py dbshell

‘dbshell’ is a handy manage.py subcommand that will give you access to the database using your DATABASES settings
You can check the tables in the database by doing:

a model is never saved to the database until the save method is explicitly called

Whats all this:

Our CD model is mapped to a database table

A default primary key is used since we have not primary_key on any of the fields

The default primary key is of the type int and is autoincremented

The table fields are selected automatically based on model fields

That is really the core of the work of the ORM: mapping classes (or models) to tables. While doing so,
django takes care of the conversion of model fields to database columns, type conversions, primary keys,
constraints and all of that. Thanks to the ORM, you don’t have to deal with the databases directly.
In fact, if you were to switch the underlying database by modifying DATABASES in settings, your application
would be least affected by it.

Now that you know a little bit about the ORM, lets see some more utilities it provides:

the object manager:

CD.objects

objects refers to the default object manager. A manager provides the way of dealing with the database.
Custom managers can be used to provide different ‘views’ of the model. More on that later.

the get method - to get a single object:

CD.objects.get(pk=1)

returns:

<CD: OK Computer by Radiohead, 2000>

that is, a single instance of our CD model. The arguments must return a unique object or else
this method will raise MultipleObjectsReturned error.

Note

arguments to the manager methods include pk for primary key, all model fields and some operators
called lookups

Use the get method on when you want to retrieve one record based on the given criteria.