Django for Designers/Starting our project

From OpenHatch wiki

Part 1: Starting our project

This tutorial goes through the process of building a simple social bookmarking application, where users can save various URLs and tag those bookmarks to make them easier to find later. Our bookmarks application will be built on top of Django, a full-featured web framework written in Python.

Activate your env

The first step is to open your terminal window, navigate to your django-for-designers folder, and activate your env:


# in django-for-designers
$ source ./bin/activate

You'll know it worked because afterwards, you'll see

(django-for-designers) $

at the front of all your terminal lines in that terminal window!

(What this did is activate a special Python environment that knows about Django and other dependencies for this tutorial. By keeping our dependencies inside a separate environment, we can keep them from interfering with any other project's dependencies--for instance, if you had one project using Django 1.4 and another using Django 1.5 on the same computer.)

Create a branch in your git repository

If you're not familiar with git, git is a version control system that tracks changes you make to files within a git repository (the folder you just cloned). You make commits in git, which are like save points in video games -- the commit messages tell you what changes are included in this commit. If later on you make some changes and delete something or mess something up, you can always go back to a previous commit and try again.

Git also has "branches"--parallel timelines where you can go off from the main branch (called "master") and try something out. It's often a good idea to start a new branch when you're writing a new feature. You can make as many commits as you want inside the branch, and it won't affect the main master timeline. You can make as many branches as you want, and branches of branches. You can even share branches with others (though we won't be doing that today). Git's branching system (and its non-centralized architecture generally) make it easy to try out new ideas in code without having to ask permission of everyone else who might be working on the same code as you. Then, when your new feature is done, you can then merge (or rebase--the exact process would take a much longer explanation) the changes back into the master timeline.

We'll be using several branches of the git repository you cloned during laptop setup for syncing up throughout the class in case you get lost. You'll need to make your own branches for playing with the code on your computer, so that it doesn't interfere w. re-syncing later.

We've created some branches for you to base your work on. You will use snapshots these as starting points throughout the tutorial. At the end of a section, you'll have your own completed work for that section available, but you'll start fresh from a pristine snapshot of what it would have looked like if you did it our way.

To make sure you have the latest collection of branches, run this command:

# in django-for-designers
$ git fetch

To make your first branch, enter:

# in django-for-designers
$ git branch my-branch-1 origin/pre-part-1
$ git checkout my-branch-1

Congratulations! You're now in a branch named my-branch-1!

(which is based off of our pre-made branch pre-part-1)

Notice that branches on your own computer have no prefix; branches that belong to others have origin/ before their names.

You can see what branch you are in (and what branches are in your repository) at any time by typing:

# in django-for-designers
$ git branch

Start your project

Let's create your first Django project, which we'll call "myproject".

$ django-admin.py startproject myproject

You'll see we made a folder called "myproject", with some files in it. Let's check them out!

# in django-for-designers
$ cd myproject/
# in django-for-designers/myproject
$ ls
    manage.py
    myproject
$ ls myproject/
    __init__.py  
    settings.py
    urls.py
    wsgi.py

These files are:

  • manage.py: A command-line utility that lets you interact with this Django project in various ways.
  • myproject/: Django auto-creates an folder within your project with the same name as your project that has a number of useful files in it. (This is a recent change; before Django 1.4, Django just put everything in the project folder instead of siloing it.)
  • myproject/__init__.py: An empty file that tells Python that this directory should be considered a Python module. Because of the __init__.py file, you can use import to import myproject.
  • myproject/settings.py: Settings/configuration for this Django project.
  • myproject/urls.py: The URL declarations for this Django project; a “table of contents” of your Django-powered site.
Django comes with some local server software included. The Django development server is not hardy enough for actual production use (please, please don't use it for sites other people are supposed to use!) but it makes it easy to see the changes you make to your web app as you build it.

Let's make sure our project works by verifying that the dev server will start:

# in django-for-designers/myproject
$ python manage.py runserver

(Note: If you see a python: can't open file error, make sure you have used cd to change into the directory with manage.py.)

You should see some output in your terminal that looks like:

Validating models...
0 errors found.
 
Django version 1.2, using settings 'myproject.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Visit http://localhost:8000 in your web browser, and you’ll see a “Welcome to Django” page, in pleasant, light-blue pastel. It worked! :)

Observe the logging that happens in the terminal where your server is running:

[24/Mar/2011 11:50:18] "GET / HTTP/1.1" 200 2057

which has the format:

DATE  METHOD URL  PROTOCOL  RESPONSE_CODE  CONTENTSIZE

Navigate to http://127.0.0.1:8000/some/url/. What changes in the terminal log?

Exit the server by returning to the terminal window where the development server is running and pressing CONTROL-C on your keyboard.

One super useful tip is to open a new terminal (a new tab, or a new window, on your convenience) and keep the runserver always open there. By default, Django's runserver will automatically reload to reflect any changes that you make, so there's no need to stop and start it.

Do that now to save you time later. Remember that you will need to cd into the right place, and activate the virtualenv again.

Version control

Before we do anything else, let’s commit our work in git.

As you recall, git lets you create checkpoints over the course of the time a program is being developed. Commits are those checkpoints. Programmers often have to go back into the history of a program to change things--whether it's to diagnose a bug or redesign how a feature works. Programmers also have to have an easy way of being able to edit the same application at the same time, and to share their edits with each other. Thus, besides saving their work the normal way, programmers commit their code using version control software. Each commit contains the diff--the "difference", all of the changes you made to your code base -- between that commit and the commit before it. Different branches in git share the commits made prior to the branching-off point, then each have their own commit history.

To make a commit, first type

# in django-for-designers/myproject
$ git status

into your terminal. This will let you know what changes git has noticed in your code and which of those changes, if any, are staged and ready to be committed.

# in django-for-designers/myproject
$ git status
# On branch my-branch-1
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   ./
nothing added to commit but untracked files present (use "git add" to track)
"Untracked files" means that git has noticed some new files inside its repository folder, but you haven't told git explicitly that you want it to "listen" for, and track, changes in those files. './' means that the folder we're in right now is currently untracked.
  • Add the folder:
# in django-for-designers/myproject
git add ./

What does git status say now?

  • git commit to commit those files. Adding the -m flag lets you say what the 'message' for the commit is in the same line:
# in django-for-designers/myproject
$ git commit -m "Initial commit of Django project for the PyCon 2013 Django tutorial"
  • Look at your changes with
    git log
    
    to see your history. Is your commit message there?

Huzzah! We committed our changes so far. Now let's make some more changes!

Set up your settings and database

Now that we have a the scaffolding for our project in place, we can get to work! First, it needs to be configured.

Open myproject/myproject/settings.py in your editor. settings.py is a Python script that only contains variable definitions. Django looks at the values of these variables when it runs your project.

In settings.py, let's find DATABASES. The DATABASES variable is a dictionary (note the ‘{}’ characters) with one key: default.

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

Notice that the value of default is itself another dictionary with information about the site’s default database.

Set your app to use a sqlite database, in the ENGINE attribute. Sqlite is great for development because is stores its data in one normal file on your system and therefore is really simple to move around with your app. It's not sturdy enough to use for a website in production, though.

'ENGINE': 'django.db.backends.sqlite3',

Set your app to use a file called 'database.db' to store information for this project.

'NAME': 'database.db',

Does database.db exist right now?

(No, but that's okay. It'll get created automatically when it's needed.)

Run git status, then git add and commit your change:

# in django-for-designers/myproject
$ git add myproject/  # this is a shortcut that will add all changes inside the named folder
$ git commit -m "set up the database for Django to use"

Even though git knows to "listen" to settings.py now, it still won't add it to the 'staging area' for your commit unless you tell it to explicitly with git add.

Notice the INSTALLED_APPS setting towards the bottom of the settings.py.

That variable (a python tuple... note the ‘()’ symbols) holds the names of all Django applications that are activated in this Django instance. Apps can be used in multiple projects, and you can package and distribute them for use by others in their projects. Some apps (as you can see) are installed by default!

Add South to our list of installed apps. (We'll need it later.)

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

Each of our applications makes use of at least one database table, so we need to create the tables in the database before we can use them. To do that, run the following command in your terminal window:

# in django-for-designers/myproject
$ python manage.py syncdb

The syncdb command looks at the INSTALLED_APPS setting and creates any necessary database tables according to the database settings in your settings.py file. You’ll see a message for each database table it creates.

When prompted, you’ll get a prompt asking you if you’d like to create a superuser account for the authentication system. Say yes! Use 'super' as your password for now.

Does database.db exist right now?

(Yes! Calling syncdb made Django realize it needed a sqlite database file, so it made one for us.)

Save and commit your work!

===Projects vs. apps distinction===

We’ve talked a little about Django apps and projects. You might be wondering what that nonsense is all about. Here are the things to know: An app is component of a website that does something. South is a Django app. So is our bookmarks app (or it will be, anyway). An app is:

  • single purpose - login, passwords, polls, forum, etc.
  • orthogonal to / independent of other apps - Bookmarks shouldn’t have to know the inside details of authentication, for example.

A project corresponds roughly to a ‘website’: it has a settings.py file, and it may have corresponding databases or other data stores that the apps interact with. As you can remember, Django automatically made a folder for us called myproject, which you can think of as the app that coordinates all the other apps and other parts of the project.

Most projects--those for more complex websites--should use multiple apps, one for each core piece of functionality. Ideally, you should reuse existing free, open source Django apps that other people have written for things like user accounts, image galleries, and other common use cases. Django Packages is a good resource for finding such apps.

You can find prewritten Django apps for things like bookmarks and tagging, but we'll be writing them ourselves for the sake of learning. :)

Start your first app

In your terminal, write:

# in django-for-designers/myproject
$ python manage.py startapp bookmarks

If you run

# in django-for-designers/myproject
$ ls

you'll see that now there is a folder called bookmarks/ in your project!

Inside that folder, you'll see:

# in django-for-designers/myproject
$ ls bookmarks/
__init__.py
models.py
tests.py
views.py

Finally, we need to edit myproject/settings.py so that Django knows about our app. Open that file up, and look for INSTALLED_APPS. Add the following to the end of the sequence, on a line of its own:

    'bookmarks',

It will then look like this:

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    # 'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
    'south',
    'bookmarks',
)

Let's commit our new app.

# in django-for-designers/myproject
$ git add bookmarks/
$ git commit -m "Made a bookmarks app"


Next page