« Back to home

Notes on Django

1. Activate an environment

Pre-install django in this env

conda create -n tutorial django=1.8
activate tutorial
mkdir tutorial
cd tutorial

2. Create requirements.txt

And install via pip (if needed):

touch requirements.txt
django==1.8 > requirements.txt
pip install -r requirements.txt

3. Init django

Create scaffold for django (note . to use current folder)

django-admin.py startproject addressbook .

C:.
β”‚   manage.py
β”‚   requirements.txt
β”‚
└───addressbook
        settings.py
        urls.py
        wsgi.py
        __init__.py

4. Create next app inside project

Invoke manage function to create app structure

python manage.py startapp contacts

C:.
β”‚   manage.py
β”‚   requirements.txt
β”‚
β”œβ”€β”€β”€addressbook
β”‚       settings.py
β”‚       settings.pyc
β”‚       urls.py
β”‚       wsgi.py
β”‚       __init__.py
β”‚       __init__.pyc
β”‚
└───contacts
    β”‚   admin.py
    β”‚   models.py
    β”‚   tests.py
    β”‚   views.py
    β”‚   __init__.py
    β”‚
    └───migrations
            __init__.py

5. Set up database details in addressbook/settings.py

Template varies between django 1.5 and 1.8. See docs

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'addresses.db'),
    }
}

6. Create a basic contact model

Modify contacts/models.py

from django.db import models


class Contact(models.Model):

    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    email = models.EmailField()

    def __str__(self):
        return self.first_name + " " + self.last_name

And sync DB

python manage.py syncdb

This will create addresses.db in your root folder

7. Register contacts as installed app

Modify settings.py to match:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'contacts',
)

Sync again

python manage.py syncdb

For Django 1.8 :

Migrations are required to apply changes to the database, such as creating tables:

python manage.py makemigrations
python manage.py migrate

Verify the model has been migrated using the shell with python manage.py shell

>>> from models.contact import Contact
>>>	Contact.objects.create(first_name='cdv', last_name='cdv', email='cdv@cdv.com')
>>> Contact.objects.all()
<Contact: cdv cdv>
>>> Contact.objects.find(first_name__startswith='c')
<Contact: cdv cdv>

Queries return a QuerySet object (lazy loader) that allows function chanining

8. Write your tests

Modify the existing file contacts/tests.py to match:

from django.test import TestCase
from contacts.models import Contact


class ContactTests(TestCase):

    def test_str(self):
        c = Contact(first_name='Kevin', last_name='Bacon')
        self.assertEqual(str(c), 'Kevin Bacon')

Then run the test with

python manage.py test

Creating test database for alias 'default'...
.
----------------------------------------------------------------------
Ran 1 test in 0.017s

OK
Destroying test database for alias 'default'...

9. Create a ListView and Template, wire them

Modify contacts/views.py to match:

from django.views.generic import ListView
from contacts.models import Contact


class ContactListView(ListView):

    model = Contact
    template_name = 'contact_list.html'

Alter urls.py to look like:

from django.conf.urls import include, url
from django.contrib import admin
import contacts.views

urlpatterns = [
    url(r'^$', contacts.views.ContactListView.as_view(),
        name='contacts-list'),
    url(r'^admin/', include(admin.site.urls)),
]

Create a template at contacts\templates\contact_list.html

<h1>Contacts</h1>

<ul>
	{% for contact in object_list %}
		<li>{{ contact }}</li>
	{% endfor %}
</ul>

Test with

python manage.py runserver

10. Add a contact form

Modify views.py to match

from django.views.generic import ListView, CreateView
from django.core.urlresolvers import reverse
from contacts.models import Contact


class ContactListView(ListView):

    model = Contact
    template_name = 'contact_list.html'


class CreateContactView(CreateView):

    model = Contact
    fields = ['first_name', 'last_name', 'email']
    template_name = 'edit_contact.html'

    def get_success_url(self):
        return reverse('contacts-list')

Create templates\contact_list.html. The csrf (cross-site request forgery token) is part of the Django specification.

<h1>
	Add contact
</h1>

<form action="{% url 'contacts-new' %}" method="POST">
	{% csrf_token %}

	<ul>
		{{ form.as_ul }}
	</ul>
	<input type="submit" value="Save" />

</form>

Add it to the urls.py file

from django.conf.urls import include, url
from django.contrib import admin
import contacts.views

urlpatterns = [
    url(r'^$', contacts.views.ContactListView.as_view(),
        name='contacts-list'),
    url(r'^new$', contacts.views.CreateContactView.as_view(),
        name='contacts-new'),
    url(r'^admin/', include(admin.site.urls)),
]

Run again and browse to http://localhost:8000/new

python manage.py runserver

Sources

  1. Effective Django

Comments

comments powered by Disqus