overview.txt 12.7 KB
Newer Older
1 2 3
==================
Django at a glance
==================
4 5 6 7 8 9 10

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

The goal of this document is to give you enough technical specifics to
understand how Django works, but this isn't intended to be a tutorial or
11
reference -- but we've got both! When you're ready to start a project, you can
12 13
:doc:`start with the tutorial </intro/tutorial01>` or :doc:`dive right into more
detailed documentation </topics/index>`.
14 15 16 17

Design your model
=================

18
Although you can use Django without a database, it comes with an
19
`object-relational mapper`_ in which you describe your database layout in Python
20
code.
21

22
.. _object-relational mapper: https://en.wikipedia.org/wiki/Object-relational_mapping
23

24
The :doc:`data-model syntax </topics/db/models>` offers many rich ways of
25
representing your models -- so far, it's been solving many years' worth of
26 27 28 29
database-schema problems. Here's a quick example:

.. snippet::
    :filename: mysite/news/models.py
30

31
    from django.db import models
32

33
    class Reporter(models.Model):
34
        full_name = models.CharField(max_length=70)
35

36
        def __str__(self):              # __unicode__ on Python 2
37
            return self.full_name
38

39
    class Article(models.Model):
40
        pub_date = models.DateField()
41
        headline = models.CharField(max_length=200)
42
        content = models.TextField()
43
        reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
44

45
        def __str__(self):              # __unicode__ on Python 2
46 47 48 49 50
            return self.headline

Install it
==========

51
Next, run the Django command-line utility to create the database tables
52 53
automatically:

54
.. code-block:: console
55

56
    $ python manage.py migrate
57

58 59 60
The :djadmin:`migrate` command looks at all your available models and creates
tables in your database for whichever tables don't already exist, as well as
optionally providing :doc:`much richer schema control </topics/migrations>`.
61 62 63 64

Enjoy the free API
==================

65 66 67
With that, you've got a free, and rich, :doc:`Python API </topics/db/queries>`
to access your data. The API is created on the fly, no code generation
necessary:
68 69

.. code-block:: python
70

71 72
    # Import the models we created from our "news" app
    >>> from news.models import Reporter, Article
73

74
    # No reporters are in the system yet.
75
    >>> Reporter.objects.all()
76
    <QuerySet []>
77

78
    # Create a new Reporter.
79
    >>> r = Reporter(full_name='John Smith')
80

81 82
    # Save the object into the database. You have to call save() explicitly.
    >>> r.save()
83

84 85 86
    # Now it has an ID.
    >>> r.id
    1
87

88
    # Now the new reporter is in the database.
89
    >>> Reporter.objects.all()
90
    <QuerySet [<Reporter: John Smith>]>
91

92 93 94
    # Fields are represented as attributes on the Python object.
    >>> r.full_name
    'John Smith'
95

96 97
    # Django provides a rich database lookup API.
    >>> Reporter.objects.get(id=1)
98
    <Reporter: John Smith>
99
    >>> Reporter.objects.get(full_name__startswith='John')
100
    <Reporter: John Smith>
101
    >>> Reporter.objects.get(full_name__contains='mith')
102
    <Reporter: John Smith>
103
    >>> Reporter.objects.get(id=2)
104 105
    Traceback (most recent call last):
        ...
106
    DoesNotExist: Reporter matching query does not exist.
107

108
    # Create an article.
109 110
    >>> from datetime import date
    >>> a = Article(pub_date=date.today(), headline='Django is cool',
111
    ...     content='Yeah.', reporter=r)
112
    >>> a.save()
113

114
    # Now the article is in the database.
115
    >>> Article.objects.all()
116
    <QuerySet [<Article: Django is cool>]>
117

118
    # Article objects get API access to related Reporter objects.
119
    >>> r = a.reporter
120 121
    >>> r.full_name
    'John Smith'
122

123
    # And vice versa: Reporter objects get API access to Article objects.
124
    >>> r.article_set.all()
125
    <QuerySet [<Article: Django is cool>]>
126

127 128 129
    # The API follows relationships as far as you need, performing efficient
    # JOINs for you behind the scenes.
    # This finds all articles by a reporter whose name starts with "John".
130
    >>> Article.objects.filter(reporter__full_name__startswith='John')
131
    <QuerySet [<Article: Django is cool>]>
132

133 134 135
    # Change an object by altering its attributes and calling save().
    >>> r.full_name = 'Billy Goat'
    >>> r.save()
136

137 138 139
    # Delete an object with delete().
    >>> r.delete()

140
A dynamic admin interface: it's not just scaffolding -- it's the whole house
141 142
============================================================================

143
Once your models are defined, Django can automatically create a professional,
144
production ready :doc:`administrative interface </ref/contrib/admin/index>` --
145
a website that lets authenticated users add, change and delete objects. It's
146
as easy as registering your model in the admin site:
147

148 149
.. snippet::
    :filename: mysite/news/models.py
150 151

    from django.db import models
152

153
    class Article(models.Model):
154
        pub_date = models.DateField()
155
        headline = models.CharField(max_length=200)
156
        content = models.TextField()
157
        reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
158

159 160
.. snippet::
    :filename: mysite/news/admin.py
161 162 163

    from django.contrib import admin

164 165
    from . import models

166
    admin.site.register(models.Article)
167 168 169 170 171

The philosophy here is that your site is edited by a staff, or a client, or
maybe just you -- and you don't want to have to deal with creating backend
interfaces just to manage content.

172 173 174
One typical workflow in creating Django apps is to create models and get the
admin sites up and running as fast as possible, so your staff (or clients) can
start populating data. Then, develop the way data is presented to the public.
175 176

Design your URLs
177
================
178 179

A clean, elegant URL scheme is an important detail in a high-quality Web
180 181
application. Django encourages beautiful URL design and doesn't put any cruft
in URLs, like ``.php`` or ``.asp``.
182

183
To design URLs for an app, you create a Python module called a :doc:`URLconf
184 185 186
</topics/http/urls>`. A table of contents for your app, it contains a simple
mapping between URL patterns and Python callback functions. URLconfs also serve
to decouple URLs from Python code.
187

188
Here's what a URLconf might look like for the ``Reporter``/``Article``
189 190 191 192
example above:

.. snippet::
    :filename: mysite/news/urls.py
193

194
    from django.conf.urls import url
195

196 197
    from . import views

198
    urlpatterns = [
199 200 201
        url(r'^articles/([0-9]{4})/$', views.year_archive),
        url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
        url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
202
    ]
203

204
The code above maps URLs, as simple `regular expressions`_, to the location of
205 206 207 208 209 210
Python callback functions ("views"). The regular expressions use parenthesis to
"capture" values from the URLs. When a user requests a page, Django runs
through each pattern, in order, and stops at the first one that matches the
requested URL. (If none of them matches, Django calls a special-case 404 view.)
This is blazingly fast, because the regular expressions are compiled at load
time.
211

212
.. _regular expressions: https://docs.python.org/howto/regex.html
213

214
Once one of the regexes matches, Django imports and calls the given view, which
215
is a simple Python function. Each view gets passed a request object --
216
which contains request metadata -- and the values captured in the regex.
217 218

For example, if a user requested the URL "/articles/2005/05/39323/", Django
219
would call the function ``news.views.article_detail(request,
220
'2005', '05', '39323')``.
221 222 223 224 225

Write your views
================

Each view is responsible for doing one of two things: Returning an
226 227 228
:class:`~django.http.HttpResponse` object containing the content for the
requested page, or raising an exception such as :class:`~django.http.Http404`.
The rest is up to you.
229 230 231

Generally, a view retrieves data according to the parameters, loads a template
and renders the template with the retrieved data. Here's an example view for
232 233 234 235
``year_archive`` from above:

.. snippet::
    :filename: mysite/news/views.py
236

237
    from django.shortcuts import render
238

239 240
    from .models import Article

241 242
    def year_archive(request, year):
        a_list = Article.objects.filter(pub_date__year=year)
243 244
        context = {'year': year, 'article_list': a_list}
        return render(request, 'news/year_archive.html', context)
245

246
This example uses Django's :doc:`template system </topics/templates>`, which has
247 248
several powerful features but strives to stay simple enough for non-programmers
to use.
249 250 251 252

Design your templates
=====================

253
The code above loads the ``news/year_archive.html`` template.
254 255 256

Django has a template search path, which allows you to minimize redundancy among
templates. In your Django settings, you specify a list of directories to check
257 258
for templates with :setting:`DIRS <TEMPLATES-DIRS>`. If a template doesn't exist
in the first directory, it checks the second, and so on.
259

260
Let's say the ``news/year_archive.html`` template was found. Here's what that
261 262
might look like:

263 264
.. snippet:: html+django
    :filename: mysite/news/templates/news/year_archive.html
265

266
    {% extends "base.html" %}
267

268
    {% block title %}Articles for {{ year }}{% endblock %}
269

270
    {% block content %}
271 272 273
    <h1>Articles for {{ year }}</h1>

    {% for article in article_list %}
274 275 276
        <p>{{ article.headline }}</p>
        <p>By {{ article.reporter.full_name }}</p>
        <p>Published {{ article.pub_date|date:"F j, Y" }}</p>
277
    {% endfor %}
278 279
    {% endblock %}

280 281
Variables are surrounded by double-curly braces. ``{{ article.headline }}``
means "Output the value of the article's headline attribute." But dots aren't
282
used only for attribute lookup. They also can do dictionary-key lookup, index
283
lookup and function calls.
284 285 286 287

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 value
of a variable. In this case, the date filter formats a Python datetime object in
Ben Longden's avatar
Ben Longden committed
288
the given format (as found in PHP's date function).
289

290 291 292 293
You can chain together as many filters as you'd like. You can write :ref:`custom
template filters <howto-writing-custom-template-filters>`. You can write
:doc:`custom template tags </howto/custom-template-tags>`, which run custom
Python code behind the scenes.
294

295
Finally, Django uses the concept of "template inheritance". That's what the
296 297 298
``{% extends "base.html" %}`` does. It means "First load the template called
'base', which has defined a bunch of blocks, and fill the blocks with the
following blocks." In short, that lets you dramatically cut down on redundancy
299
in templates: each template has to define only what's unique to that template.
300

301
Here's what the "base.html" template, including the use of :doc:`static files
302
</howto/static-files/index>`, might look like:
303

304 305
.. snippet:: html+django
    :filename: mysite/templates/base.html
306

307
    {% load static %}
308 309
    <html>
    <head>
310
        <title>{% block title %}{% endblock %}</title>
311 312
    </head>
    <body>
313
        <img src="{% static "images/sitelogo.png" %}" alt="Logo" />
314 315 316 317 318 319
        {% block content %}{% endblock %}
    </body>
    </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 makes a site redesign as
320
easy as changing a single file -- the base template.
321

322 323
It also lets you create multiple versions of a site, with different base
templates, while reusing child templates. Django's creators have used this
324 325
technique to create strikingly different mobile versions of sites -- simply by
creating a new base template.
326

327 328 329
Note that you don't have to use Django's template system if you prefer another
system. While Django's template system is particularly well-integrated with
Django's model layer, nothing forces you to use it. For that matter, you don't
330 331 332 333
have to use Django's database API, either. You can use another database
abstraction layer, you can read XML files, you can read files off disk, or
anything you want. Each piece of Django -- models, views, templates -- is
decoupled from the next.
334 335 336 337 338 339 340

This is just the surface
========================

This has been only a quick overview of Django's functionality. Some more useful
features:

341 342
* A :doc:`caching framework </topics/cache>` that integrates with memcached
  or other backends.
343

344 345
* A :doc:`syndication framework </ref/contrib/syndication>` that makes
  creating RSS and Atom feeds as easy as writing a small Python class.
346

347 348
* More sexy automatically-generated admin features -- this overview barely
  scratched the surface.
349

350 351
The next obvious steps are for you to `download Django`_, read :doc:`the
tutorial </intro/tutorial01>` and join `the community`_. Thanks for your
352
interest!
353

354 355
.. _download Django: https://www.djangoproject.com/download/
.. _the community: https://www.djangoproject.com/community/