Django at a glance

Because Django was developed in a fast-paced newsroom environment, it wasdesigned to make common Web-development tasks fast and easy. Here’s an informaloverview of how to write a database-driven Web app with Django.

The goal of this document is to give you enough technical specifics tounderstand how Django works, but this isn’t intended to be a tutorial orreference – but we’ve got both! When you’re ready to start a project, you canstart with the tutorial or dive right into moredetailed documentation.

Design your model

Although you can use Django without a database, it comes with anobject-relational mapper in which you describe your database layout in Pythoncode.

The data-model syntax offers many rich ways ofrepresenting your models – so far, it’s been solving many years’ worth ofdatabase-schema problems. Here’s a quick example:

mysite/news/models.py

  1. from django.db import models
  2.  
  3. class Reporter(models.Model):
  4. full_name = models.CharField(max_length=70)
  5.  
  6. def __str__(self):
  7. return self.full_name
  8.  
  9. class Article(models.Model):
  10. pub_date = models.DateField()
  11. headline = models.CharField(max_length=200)
  12. content = models.TextField()
  13. reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
  14.  
  15. def __str__(self):
  16. return self.headline

Install it

Next, run the Django command-line utilities to create the database tablesautomatically:

  1. $ python manage.py makemigrations
  2. $ python manage.py migrate
  1. ...\> py manage.py makemigrations
  2. ...\> py manage.py migrate

The makemigrations command looks at all your available models andcreates migrations for whichever tables don’t already exist. migrateruns the migrations and creates tables in your database, as well as optionallyproviding much richer schema control.

Enjoy the free API

With that, you’ve got a free, and rich, Python APIto access your data. The API is created on the fly, no code generationnecessary:

  1. # Import the models we created from our "news" app
  2. >>> from news.models import Article, Reporter
  3.  
  4. # No reporters are in the system yet.
  5. >>> Reporter.objects.all()
  6. <QuerySet []>
  7.  
  8. # Create a new Reporter.
  9. >>> r = Reporter(full_name='John Smith')
  10.  
  11. # Save the object into the database. You have to call save() explicitly.
  12. >>> r.save()
  13.  
  14. # Now it has an ID.
  15. >>> r.id
  16. 1
  17.  
  18. # Now the new reporter is in the database.
  19. >>> Reporter.objects.all()
  20. <QuerySet [<Reporter: John Smith>]>
  21.  
  22. # Fields are represented as attributes on the Python object.
  23. >>> r.full_name
  24. 'John Smith'
  25.  
  26. # Django provides a rich database lookup API.
  27. >>> Reporter.objects.get(id=1)
  28. <Reporter: John Smith>
  29. >>> Reporter.objects.get(full_name__startswith='John')
  30. <Reporter: John Smith>
  31. >>> Reporter.objects.get(full_name__contains='mith')
  32. <Reporter: John Smith>
  33. >>> Reporter.objects.get(id=2)
  34. Traceback (most recent call last):
  35. ...
  36. DoesNotExist: Reporter matching query does not exist.
  37.  
  38. # Create an article.
  39. >>> from datetime import date
  40. >>> a = Article(pub_date=date.today(), headline='Django is cool',
  41. ... content='Yeah.', reporter=r)
  42. >>> a.save()
  43.  
  44. # Now the article is in the database.
  45. >>> Article.objects.all()
  46. <QuerySet [<Article: Django is cool>]>
  47.  
  48. # Article objects get API access to related Reporter objects.
  49. >>> r = a.reporter
  50. >>> r.full_name
  51. 'John Smith'
  52.  
  53. # And vice versa: Reporter objects get API access to Article objects.
  54. >>> r.article_set.all()
  55. <QuerySet [<Article: Django is cool>]>
  56.  
  57. # The API follows relationships as far as you need, performing efficient
  58. # JOINs for you behind the scenes.
  59. # This finds all articles by a reporter whose name starts with "John".
  60. >>> Article.objects.filter(reporter__full_name__startswith='John')
  61. <QuerySet [<Article: Django is cool>]>
  62.  
  63. # Change an object by altering its attributes and calling save().
  64. >>> r.full_name = 'Billy Goat'
  65. >>> r.save()
  66.  
  67. # Delete an object with delete().
  68. >>> r.delete()

A dynamic admin interface: it’s not just scaffolding – it’s the whole house

Once your models are defined, Django can automatically create a professional,production ready administrative interface –a website that lets authenticated users add, change and delete objects. Theonly step required is to register your model in the admin site:

mysite/news/models.py

  1. from django.db import models
  2.  
  3. class Article(models.Model):
  4. pub_date = models.DateField()
  5. headline = models.CharField(max_length=200)
  6. content = models.TextField()
  7. reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)

mysite/news/admin.py

  1. from django.contrib import admin
  2.  
  3. from . import models
  4.  
  5. admin.site.register(models.Article)

The philosophy here is that your site is edited by a staff, or a client, ormaybe just you – and you don’t want to have to deal with creating backendinterfaces only to manage content.

One typical workflow in creating Django apps is to create models and get theadmin sites up and running as fast as possible, so your staff (or clients) canstart populating data. Then, develop the way data is presented to the public.

Design your URLs

A clean, elegant URL scheme is an important detail in a high-quality Webapplication. Django encourages beautiful URL design and doesn’t put any cruftin URLs, like .php or .asp.

To design URLs for an app, you create a Python module called a URLconf. A table of contents for your app, it contains a mappingbetween URL patterns and Python callback functions. URLconfs also serve todecouple URLs from Python code.

Here’s what a URLconf might look like for the Reporter/Articleexample above:

mysite/news/urls.py

  1. from django.urls import path
  2.  
  3. from . import views
  4.  
  5. urlpatterns = [
  6. path('articles/<int:year>/', views.year_archive),
  7. path('articles/<int:year>/<int:month>/', views.month_archive),
  8. path('articles/<int:year>/<int:month>/<int:pk>/', views.article_detail),
  9. ]

The code above maps URL paths to Python callback functions (“views”). The pathstrings use parameter tags to “capture” values from the URLs. When a userrequests a page, Django runs through each path, in order, and stops at thefirst one that matches the requested URL. (If none of them matches, Djangocalls a special-case 404 view.) This is blazingly fast, because the paths arecompiled into regular expressions at load time.

Once one of the URL patterns matches, Django calls the given view, which is aPython function. Each view gets passed a request object – which containsrequest metadata – and the values captured in the pattern.

For example, if a user requested the URL “/articles/2005/05/39323/”, Djangowould call the function news.views.article_detail(request,year=2005, month=5, pk=39323).

Write your views

Each view is responsible for doing one of two things: Returning anHttpResponse object containing the content for therequested page, or raising an exception such as Http404.The rest is up to you.

Generally, a view retrieves data according to the parameters, loads a templateand renders the template with the retrieved data. Here’s an example view foryear_archive from above:

mysite/news/views.py

  1. from django.shortcuts import render
  2.  
  3. from .models import Article
  4.  
  5. def year_archive(request, year):
  6. a_list = Article.objects.filter(pub_date__year=year)
  7. context = {'year': year, 'article_list': a_list}
  8. return render(request, 'news/year_archive.html', context)

This example uses Django’s template system, which hasseveral powerful features but strives to stay simple enough for non-programmersto use.

Design your templates

The code above loads the news/year_archive.html template.

Django has a template search path, which allows you to minimize redundancy amongtemplates. In your Django settings, you specify a list of directories to checkfor templates with DIRS. If a template doesn’t existin the first directory, it checks the second, and so on.

Let’s say the news/year_archive.html template was found. Here’s what thatmight look like:

mysite/news/templates/news/year_archive.html

  1. {% extends "base.html" %}
  2.  
  3. {% block title %}Articles for {{ year }}{% endblock %}
  4.  
  5. {% block content %}
  6. <h1>Articles for {{ year }}</h1>
  7.  
  8. {% for article in article_list %}
  9. <p>{{ article.headline }}</p>
  10. <p>By {{ article.reporter.full_name }}</p>
  11. <p>Published {{ article.pub_date|date:"F j, Y" }}</p>
  12. {% endfor %}
  13. {% endblock %}

Variables are surrounded by double-curly braces. {{ article.headline }}means “Output the value of the article’s headline attribute.” But dots aren’tused only for attribute lookup. They also can do dictionary-key lookup, indexlookup and function calls.

Note {{ article.pub_date|date:"F j, Y" }} uses a Unix-style “pipe” (the “|”character). This is called a template filter, and it’s a way to filter the valueof a variable. In this case, the date filter formats a Python datetime object inthe given format (as found in PHP’s date function).

You can chain together as many filters as you’d like. You can write customtemplate filters. You can writecustom template tags, which run customPython code behind the scenes.

Finally, Django uses the concept of “template inheritance”. That’s what the{% extends "base.html" %} does. It means “First load the template called‘base’, which has defined a bunch of blocks, and fill the blocks with thefollowing blocks.” In short, that lets you dramatically cut down on redundancyin templates: each template has to define only what’s unique to that template.

Here’s what the “base.html” template, including the use of static files, might look like:

mysite/templates/base.html

  1. {% load static %}
  2. <html>
  3. <head>
  4. <title>{% block title %}{% endblock %}</title>
  5. </head>
  6. <body>
  7. <img src="{% static "images/sitelogo.png" %}" alt="Logo">
  8. {% block content %}{% endblock %}
  9. </body>
  10. </html>

Simplistically, it defines the look-and-feel of the site (with the site’s logo),and provides “holes” for child templates to fill. This means that a site redesigncan be done by changing a single file – the base template.

It also lets you create multiple versions of a site, with different basetemplates, while reusing child templates. Django’s creators have used thistechnique to create strikingly different mobile versions of sites by onlycreating a new base template.

Note that you don’t have to use Django’s template system if you prefer anothersystem. While Django’s template system is particularly well-integrated withDjango’s model layer, nothing forces you to use it. For that matter, you don’thave to use Django’s database API, either. You can use another databaseabstraction layer, you can read XML files, you can read files off disk, oranything you want. Each piece of Django – models, views, templates – isdecoupled from the next.

This is just the surface

This has been only a quick overview of Django’s functionality. Some more usefulfeatures: