mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	git-svn-id: http://code.djangoproject.com/svn/django/trunk@1291 bcc190cf-cafb-0310-a4f2-bffc1f526a37
		
			
				
	
	
		
			294 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			294 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| ==================
 | |
| Django at a glance
 | |
| ==================
 | |
| 
 | |
| 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
 | |
| reference. Please see our more-detailed Django documentation_ when you're ready
 | |
| to start a project.
 | |
| 
 | |
| .. _documentation: http://www.djangoproject.com/documentation/
 | |
| 
 | |
| Design your model
 | |
| =================
 | |
| 
 | |
| Start by describing your database layout in Python code. Django's data-model API
 | |
| offers many rich ways of representing your models -- so far, it's been
 | |
| solving two years' worth of database-schema problems. Here's a quick example::
 | |
| 
 | |
|     class Reporter(meta.Model):
 | |
|         full_name = meta.CharField(maxlength=70)
 | |
| 
 | |
|         def __repr__(self):
 | |
|             return self.full_name
 | |
| 
 | |
|     class Article(meta.Model):
 | |
|         pub_date = meta.DateTimeField()
 | |
|         headline = meta.CharField(maxlength=200)
 | |
|         article = meta.TextField()
 | |
|         reporter = meta.ForeignKey(Reporter)
 | |
| 
 | |
|         def __repr__(self):
 | |
|             return self.headline
 | |
| 
 | |
| Install it
 | |
| ==========
 | |
| 
 | |
| Next, run the Django command-line utility. It'll create the database tables for
 | |
| you automatically, in the database specified in your Django settings. Django
 | |
| works best with PostgreSQL, although we've recently added beta MySQL
 | |
| support and other database adapters are on the way::
 | |
| 
 | |
|     django-admin.py install news
 | |
| 
 | |
| Enjoy the free API
 | |
| ==================
 | |
| 
 | |
| With that, you've got a free, and rich, Python API to access your data. The API
 | |
| is created on the fly: No code generation necessary::
 | |
| 
 | |
|     # Modules are dynamically created within django.models.
 | |
|     # Their names are plural versions of the model class names.
 | |
|     >>> from django.models.news import reporters, articles
 | |
| 
 | |
|     # No reporters are in the system yet.
 | |
|     >>> reporters.get_list()
 | |
|     []
 | |
| 
 | |
|     # Create a new Reporter.
 | |
|     >>> r = reporters.Reporter(full_name='John Smith')
 | |
| 
 | |
|     # Save the object into the database. You have to call save() explicitly.
 | |
|     >>> r.save()
 | |
| 
 | |
|     # Now it has an ID.
 | |
|     >>> r.id
 | |
|     1
 | |
| 
 | |
|     # Now the new reporter is in the database.
 | |
|     >>> reporters.get_list()
 | |
|     [John Smith]
 | |
| 
 | |
|     # Fields are represented as attributes on the Python object.
 | |
|     >>> r.full_name
 | |
|     'John Smith'
 | |
| 
 | |
|     # Django provides a rich database lookup API that's entirely driven by keyword arguments.
 | |
|     >>> reporters.get_object(id__exact=1)
 | |
|     John Smith
 | |
|     >>> reporters.get_object(full_name__startswith='John')
 | |
|     John Smith
 | |
|     >>> reporters.get_object(full_name__contains='mith')
 | |
|     John Smith
 | |
|     >>> reporters.get_object(id__exact=2)
 | |
|     Traceback (most recent call last):
 | |
|         ...
 | |
|     django.models.news.ReporterDoesNotExist: Reporter does not exist for {'id__exact': 2}
 | |
| 
 | |
|     # Lookup by a primary key is the most common case, so Django provides a
 | |
|     # shortcut for primary-key exact lookups.
 | |
|     # The following is identical to reporters.get_object(id__exact=1).
 | |
|     >>> reporters.get_object(pk=1)
 | |
|     John Smith
 | |
| 
 | |
|     # Create an article.
 | |
|     >>> from datetime import datetime
 | |
|     >>> a = articles.Article(pub_date=datetime.now(), headline='Django is cool', article='Yeah.', reporter_id=1)
 | |
|     >>> a.save()
 | |
| 
 | |
|     # Now the article is in the database.
 | |
|     >>> articles.get_list()
 | |
|     [Django is cool]
 | |
| 
 | |
|     # Article objects get API access to related Reporter objects.
 | |
|     >>> r = a.get_reporter()
 | |
|     >>> r.full_name
 | |
|     'John Smith'
 | |
| 
 | |
|     # And vice versa: Reporter objects get API access to Article objects.
 | |
|     >>> r.get_article_list()
 | |
|     [Django is cool]
 | |
| 
 | |
|     # The API follows relationships as far as you need.
 | |
|     # Find all articles by a reporter whose name starts with "John".
 | |
|     >>> articles.get_list(reporter__full_name__startswith="John")
 | |
|     [Django is cool]
 | |
| 
 | |
|     # Change an object by altering its attributes and calling save().
 | |
|     >>> r.full_name = 'Billy Goat'
 | |
|     >>> r.save()
 | |
| 
 | |
|     # Delete an object with delete().
 | |
|     >>> 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 an administrative
 | |
| interface -- a Web site that lets authenticated users add, change and
 | |
| delete objects. It's as easy as adding an extra ``admin`` attribute to your
 | |
| model classes::
 | |
| 
 | |
|     class Article(meta.Model):
 | |
|         pub_date = meta.DateTimeField()
 | |
|         headline = meta.CharField(maxlength=200)
 | |
|         article = meta.TextField()
 | |
|         reporter = meta.ForeignKey(Reporter)
 | |
|         class META:
 | |
|             admin = meta.Admin()
 | |
| 
 | |
| 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.
 | |
| 
 | |
| Our typical workflow at World Online is to create models and get the admin sites
 | |
| up and running as fast as possible, so our staff journalists can start
 | |
| populating data. Then we 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 Web
 | |
| application. Django lets you design URLs however you want, with no framework
 | |
| limitations.
 | |
| 
 | |
| To design URLs for an app, you create a Python module. For the above
 | |
| Reporter/Article example, here's what that might look like::
 | |
| 
 | |
|     from django.conf.urls.defaults import *
 | |
| 
 | |
|     urlpatterns = patterns('',
 | |
|         (r'^/articles/(?P<year>\d{4})/$', 'myproject.news.views.year_archive'),
 | |
|         (r'^/articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'myproject.news.views.month_archive'),
 | |
|         (r'^/articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<article_id>\d+)/$', 'myproject.news.views.article_detail'),
 | |
|     )
 | |
| 
 | |
| The code above maps URLs, as regular expressions, to the location of 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
 | |
| regular expression, in order, and stops at the first one that matches the
 | |
| requested URL. (If none of them matches, Django calls a special 404 view.) This
 | |
| is blazingly fast, because the regular expressions are compiled at load time.
 | |
| 
 | |
| Once one of the regexes matches, Django imports and calls the given view, which
 | |
| is a simple Python function. Each view gets passed a request object --
 | |
| which contains request metadata and lets you access GET and POST data as simple
 | |
| dictionaries -- and the values captured in the regex, via keyword
 | |
| arguments.
 | |
| 
 | |
| For example, if a user requested the URL "/articles/2005/05/39323/", Django
 | |
| would call the function ``myproject.news.views.article_detail(request,
 | |
| year='2005', month='05', article_id='39323')``.
 | |
| 
 | |
| Write your views
 | |
| ================
 | |
| 
 | |
| Each view is responsible for doing one of two things: Returning an
 | |
| ``HttpResponse`` object containing the content for the requested 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 template
 | |
| and renders the template with the retrieved data. Here's an example view for
 | |
| article_detail from above::
 | |
| 
 | |
|     def article_detail(request, year, month, article_id):
 | |
|         # Use the Django API to find an object matching the URL criteria.
 | |
|         a = get_object_or_404(articles, pub_date__year=year, pub_date__month=month, pk=article_id)
 | |
|         return render_to_response('news/article_detail', {'article': a})
 | |
| 
 | |
| This example uses Django's template system, which has several key features.
 | |
| 
 | |
| Design your templates
 | |
| =====================
 | |
| 
 | |
| The code above loads the ``news/article_detail`` template.
 | |
| 
 | |
| 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
 | |
| for templates. If a template doesn't exist in the first directory, it checks the
 | |
| second, and so on.
 | |
| 
 | |
| Let's say the ``news/article_detail`` template was found. Here's what that might
 | |
| look like::
 | |
| 
 | |
|     {% extends "base" %}
 | |
| 
 | |
|     {% block title %}{{ article.headline }}{% endblock %}
 | |
| 
 | |
|     {% block content %}
 | |
|     <h1>{{ article.headline }}</h1>
 | |
|     <p>By {{ article.get_reporter.full_name }}</p>
 | |
|     <p>Published {{ article.pub_date|date:"F j, Y" }}</p>
 | |
|     {{ article.article }}
 | |
|     {% endblock %}
 | |
| 
 | |
| 
 | |
| It should look straightforward. Variables are surrounded by double-curly braces.
 | |
| ``{{ article.headline }}`` means "Output the value of the article's headline
 | |
| attribute." But dots aren't used only for attribute lookup: They also can do
 | |
| dictionary-key lookup, index lookup and function calls (as is the case with
 | |
| ``article.get_reporter``).
 | |
| 
 | |
| 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
 | |
| the given format (as found in PHP's date function; yes, there is one good idea
 | |
| in PHP).
 | |
| 
 | |
| You can chain together as many filters as you'd like. You can write custom
 | |
| filters. You can write custom template tags, which run custom Python code behind
 | |
| the scenes.
 | |
| 
 | |
| Finally, Django uses the concept of template inheritance: That's what the ``{%
 | |
| extends "base" %}`` 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 in templates: Each
 | |
| template has to define only what's unique to that template.
 | |
| 
 | |
| Here's what the "base" template might look like::
 | |
| 
 | |
|     <html>
 | |
|     <head>
 | |
|         <title>{% block title %}{% endblock %}</title>
 | |
|     </head>
 | |
|     <body>
 | |
|         <img src="sitelogo.gif" alt="Logo" />
 | |
|         {% 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
 | |
| easy as changing a single file -- the base template.
 | |
| 
 | |
| 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
 | |
| have to use Django's 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.
 | |
| 
 | |
| This is just the surface
 | |
| ========================
 | |
| 
 | |
| This has been only a quick overview of Django's functionality. Some more useful
 | |
| features:
 | |
| 
 | |
|     * A caching framework that integrates with memcached or other backends.
 | |
|     * A syndication framework that makes creating RSS and Atom feeds as easy as
 | |
|       writing a small Python class.
 | |
|     * More sexy automatically-generated admin features -- this overview barely
 | |
|       scratched the surface.
 | |
| 
 | |
| The next obvious steps are for you to `download Django`_, read `the tutorial`_
 | |
| and join `the community`_. Thanks for your interest!
 | |
| 
 | |
| .. _download Django: http://www.djangoproject.com/download/
 | |
| .. _the tutorial: http://www.djangoproject.com/documentation/tutorial1/
 | |
| .. _the community: http://www.djangoproject.com/community/
 |