diff options
| author | Georg Bauer <gb@hugo.westfalen.de> | 2005-10-14 21:33:45 +0000 |
|---|---|---|
| committer | Georg Bauer <gb@hugo.westfalen.de> | 2005-10-14 21:33:45 +0000 |
| commit | 2a2e2fb6aa7f46a7ada2a320c775a315045f8b83 (patch) | |
| tree | 1c00ef17cc6d0f09b4559375705f3fba1e2887da /docs | |
| parent | 2ffca1711ddd58ce0457bbf972a25402b746b73b (diff) | |
| parent | 083b4f9001f3968138c4d0c34ab741cf7be97f43 (diff) | |
i18n: merged up to r868
git-svn-id: http://code.djangoproject.com/svn/django/branches/i18n@869 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/design_philosophies.txt | 244 | ||||
| -rw-r--r-- | docs/forms.txt | 36 | ||||
| -rw-r--r-- | docs/sessions.txt | 4 | ||||
| -rw-r--r-- | docs/templates.txt | 84 | ||||
| -rw-r--r-- | docs/templates_python.txt | 10 | ||||
| -rw-r--r-- | docs/tutorial03.txt | 9 | ||||
| -rw-r--r-- | docs/tutorial04.txt | 4 |
7 files changed, 306 insertions, 85 deletions
diff --git a/docs/design_philosophies.txt b/docs/design_philosophies.txt new file mode 100644 index 0000000000..2084c992a5 --- /dev/null +++ b/docs/design_philosophies.txt @@ -0,0 +1,244 @@ +=================== +Design philosophies +=================== + +This document explains some of the fundamental philosophies Django's developers +have used in creating the framework. Its goal is to explain the past and guide +the future. + +Overall +======= + +Loose coupling +-------------- + +A fundamental goal of Django's stack is `loose coupling and tight cohesion`_. +The various layers of the framework shouldn't "know" about each other unless +absolutely necessary. + +For example, the template system knows nothing about Web requests, the database +layer knows nothing about data display and the view system doesn't care which +template system a programmer uses. + +.. _`loose coupling and tight cohesion`: http://c2.com/cgi/wiki?CouplingAndCohesion + +Less code +--------- + +Django apps should use as little code as possible; they should lack boilerplate. +Django should take full advantage of Python's dynamic capabilities, such as +introspection. + +Quick development +----------------- + +The point of a Web framework in the 21st century is to make the tedious aspects +of Web development fast. Django should allow for incredibly quick Web +development. + +Don't repeat yourself (DRY) +--------------------------- + +Every distinct concept and/or piece of data should live in one, and only one, +place. Redundancy is bad. Normalization is good. + +The framework, within reason, should deduce as much as possible from as little +as possible. + +Explicit is better than implicit +-------------------------------- + +This, a `core Python principle`_, means Django shouldn't do too much "magic." +Magic shouldn't happen unless there's a really good reason for it. + +.. _`core Python principle`: http://www.python.org/doc/Humor.html#zen + +Consistency +----------- + +The framework should be consistent at all levels. Consistency applies to +everything from low-level (the Python coding style used) to high-level (the +"experience" of using Django). + +Models +====== + +Explicit is better than implicit +-------------------------------- + +Fields shouldn't assume certain behaviors based solely on the name of the +field. This requires too much knowledge of the system and is prone to errors. +Instead, behaviors should be based on keyword arguments and, in some cases, on +the type of the field. + +Include all relevant domain logic +--------------------------------- + +Models should encapsulate every aspect of an "object," following Martin +Fowler's `Active Record`_ design pattern. + +This is why model-specific admin options are included in the model itself; data +related to a model should be stored *in* the model. + +.. _`Active Record`: http://www.martinfowler.com/eaaCatalog/activeRecord.html + +Database API +============ + +The core goals of the database API are: + +SQL efficiency +-------------- + +It should execute SQL statements as few times as possible, and it should +optimize statements internally. + +This is why developers need to call ``save()`` explicitly, rather than the +framework saving things behind the scenes silently. + +This is also why the ``select_related`` argument exists. It's an optional +performance booster for the common case of selecting "every related object." + +Terse, powerful syntax +---------------------- + +The database API should allow rich, expressive statements in as little syntax +as possible. It should not rely on importing other modules or helper objects. + +Joins should be performed automatically, behind the scenes, when necessary. + +Every object should be able to access every related object, systemwide. This +access should work both ways. + +Option to drop into raw SQL easily, when needed +----------------------------------------------- + +The database API should realize it's a shortcut but not necessarily an +end-all-be-all. The framework should make it easy to write custom SQL -- entire +statements, or just custom ``WHERE`` clauses as custom parameters to API calls. + +URL design +========== + +Loose coupling +-------------- + +URLs in a Django app should not be coupled to the underlying Python code. Tying +URLs to Python function names is a Bad And Ugly Thing. + +Along these lines, the Django URL system should allow URLs for the same app to +be different in different contexts. For example, one site may put stories at +``/stories/``, while another may use ``/news/``. + +Infinite flexibility +-------------------- + +URLs should be as flexible as possible. Any conceivable URL design should be +allowed. + +Encourage best practices +------------------------ + +The framework should make it just as easy (or even easier) for a developer to +design pretty URLs than ugly ones. + +File extensions in Web-page URLs should be avoided. + +Definitive URLs +--------------- + +Technically, ``foo.com/bar`` and ``foo.com/bar/`` are two different URLs, and +search-engine robots (and some Web traffic-analyzing tools) would treat them as +separate pages. Django should make an effort to "normalize" URLs so that +search-engine robots don't get confused. + +This is the reasoning behind the ``APPEND_SLASH`` setting. + +Template system +=============== + +Separate logic from presentation +-------------------------------- + +We see a template system as a tool that controls presentation and +presentation-related logic -- and that's it. The template system shouldn't +support functionality that goes beyond this basic goal. + +If we wanted to put everything in templates, we'd be using PHP. Been there, +done that, wised up. + +Discourage redundancy +--------------------- + +The majority of dynamic Web sites use some sort of common sitewide design -- +a common header, footer, navigation bar, etc. The Django template system should +make it easy to store those elements in a single place, eliminating duplicate +code. + +This is the philosophy behind template inheritance. + +Be decoupled from HTML +---------------------- + +The template system shouldn't be designed so that it only outputs HTML. It +should be equally good at generating other text-based formats, or just plain +text. + +Assume designer competence +-------------------------- + +The template system shouldn't be designed so that templates necessarily are +displayed nicely in WYSIWYG editors such as Dreamweaver. That is too severe of +a limitation and wouldn't allow the syntax to be as nice as it is. Django +expects template authors are comfortable editing HTML directly. + +Treat whitespace obviously +-------------------------- + +The template system shouldn't do magic things with whitespace. If a template +includes whitespace, the system should treat the whitespace as it treats text +-- just display it. + +Don't invent a programming language +----------------------------------- + +The template system intentionally doesn't allow the following: + + * Assignment to variables + * Advanced logic + +The goal is not to invent a programming language. The goal is to offer just +enough programming-esque functionality, such as branching and looping, that is +essential for making presentation-related decisions. + +Extensibility +------------- + +The template system should recognize that advanced template authors may want +to extend its technology. + +This is the philosophy behind custom template tags and filters. + +Views +===== + +Simplicity +---------- + +Writing a view should be as simple as writing a Python function. Developers +shouldn't have to instantiate a class when a function will do. + +Use request objects +------------------- + +Views should have access to a request object -- an object that stores metadata +about the current request. The object should be passed directly to a view +function, rather than the view function having to access the request data from +a global variable. This makes it light, clean and easy to test views by passing +in "fake" request objects. + +Loose coupling +-------------- + +A view shouldn't care about which template system the developer uses -- or even +whether a template system is used at all. diff --git a/docs/forms.txt b/docs/forms.txt index c93db95bcd..969ebd428d 100644 --- a/docs/forms.txt +++ b/docs/forms.txt @@ -65,9 +65,8 @@ Using the ``AddManipulator`` We'll start with the ``AddManipulator``. Here's a very simple view that takes POSTed data from the browser and creates a new ``Place`` object:: - from django.core import template_loader from django.core.exceptions import Http404 - from django.core.extensions import DjangoContext as Context + from django.core.extensions import render_to_response from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect from django.models.places import places from django.core import formfields @@ -112,13 +111,7 @@ view with a form that submits to this flawed creation view:: # Create a FormWrapper object that the template can use. Ignore # the last two arguments to FormWrapper for now. form = formfields.FormWrapper(places.AddManipulator(), {}, {}) - - # Create a template, context and response. - t = template_loader.get_template('places/naive_create_form') - c = Context(request, { - 'form': form - }) - return HttpResponse(t.render(c)) + return render_to_response('places/naive_create_form', {'form': form}) (This view, as well as all the following ones, has the same imports as in the first example above.) @@ -169,11 +162,7 @@ creation view that takes validation into account:: # Check for validation errors errors = manipulator.get_validation_errors(new_data) if errors: - t = template_loader.get_template('places/errors') - c = Context(request, { - 'errors': errors - } - return HttpResponse(t.render(c)) + return render_to_response('places/errors', {'errors': errors}) else: manipulator.do_html2python(request.POST) new_place = manipulator.save(request.POST) @@ -245,11 +234,7 @@ Below is the finished view:: # Create the FormWrapper, template, context, response. form = formfields.FormWrapper(manipulator, new_data, errors) - t = template_loader.get_template("places/create_form") - c = Context(request, { - 'form': form, - }) - return HttpResponse(t.render(c)) + return render_to_response('places/create_form', {'form': form}) and here's the ``create_form`` template:: @@ -338,12 +323,7 @@ about editing an existing one? It's shockingly similar to creating a new one:: new_data = place.__dict__ form = formfields.FormWrapper(manipulator, new_data, errors) - t = template_loader.get_template("places/edit_form") - c = Context(request, { - 'form': form, - 'place': place, - }) - return HttpResponse(t.render(c)) + return render_to_response('places/edit_form', {'form': form, 'place': place}) The only real differences are: @@ -422,11 +402,7 @@ Here's a simple function that might drive the above form:: else: errors = new_data = {} form = formfields.FormWrapper(manipulator, new_data, errors) - t = template_loader.get_template("contact_form") - c = Context(request, { - 'form': form, - }) - return HttpResponse(t.render(c)) + return render_to_response('contact_form', {'form': form}) Validators ========== diff --git a/docs/sessions.txt b/docs/sessions.txt index 22d06fdedd..b18ca25a2c 100644 --- a/docs/sessions.txt +++ b/docs/sessions.txt @@ -136,9 +136,7 @@ Here's a typical usage example:: else: return HttpResponse("Please enable cookies and try again.") request.session.set_test_cookie() - t = template_loader.get_template("foo/login_form") - c = Context(request) - return HttpResponse(t.render(c)) + return render_to_response('foo/login_form') Using sessions out of views =========================== diff --git a/docs/templates.txt b/docs/templates.txt index a6848a9638..843ed0cbaa 100644 --- a/docs/templates.txt +++ b/docs/templates.txt @@ -376,9 +376,9 @@ Built-in tag reference ========================== ================================================ ``forloop.counter`` The current iteration of the loop (1-indexed) ``forloop.counter0`` The current iteration of the loop (0-indexed) - ``forloop.revcounter`` The number of iterations from the end of the + ``forloop.revcounter`` The number of iterations from the end of the loop (1-indexed) - ``forloop.revcounter0`` The number of iterations from the end of the + ``forloop.revcounter0`` The number of iterations from the end of the loop (0-indexed) ``forloop.first`` True if this is the first time through the loop ``forloop.last`` True if this is the last time through the loop @@ -569,25 +569,28 @@ Built-in filter reference ------------------------- ``add`` - Adds the arg to the value + Adds the arg to the value. ``addslashes`` - Adds slashes - useful for passing strings to JavaScript, for example. + Adds slashes. Useful for passing strings to JavaScript, for example. ``capfirst`` - Capitalizes the first character of the value + Capitalizes the first character of the value. ``center`` - Centers the value in a field of a given width + Centers the value in a field of a given width. ``cut`` - Removes all values of arg from the given string + Removes all values of arg from the given string. ``date`` - Formats a date according to the given format (same as the ``now`` tag) + Formats a date according to the given format (same as the ``now`` tag). ``default`` - If value is unavailable, use given default + If value is unavailable, use given default. + +``default_if_none`` + If value is ``None``, use given default. ``dictsort`` Takes a list of dicts, returns that list sorted by the property given in the @@ -598,24 +601,24 @@ Built-in filter reference given in the argument. ``divisibleby`` - Returns true if the value is divisible by the argument + Returns true if the value is divisible by the argument. ``escape`` - Escapes a string's HTML + Escapes a string's HTML. ``filesizeformat`` Format the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB, 102 bytes, etc). ``first`` - Returns the first item in a list + Returns the first item in a list. ``fix_ampersands`` - Replaces ampersands with ``&`` entities + Replaces ampersands with ``&`` entities. ``floatformat`` Displays a floating point number as 34.2 (with one decimal places) - but - only if there's a point to be displayed + only if there's a point to be displayed. ``get_digit`` Given a whole number, returns the requested digit of it, where 1 is the @@ -624,52 +627,52 @@ Built-in filter reference or if argument is less than 1). Otherwise, output is always an integer. ``join`` - Joins a list with a string, like Python's ``str.join(list)`` + Joins a list with a string, like Python's ``str.join(list)``. ``length`` - Returns the length of the value - useful for lists + Returns the length of the value. Useful for lists. ``length_is`` - Returns a boolean of whether the value's length is the argument + Returns a boolean of whether the value's length is the argument. ``linebreaks`` - Converts newlines into <p> and <br />s + Converts newlines into <p> and <br />s. ``linebreaksbr`` - Converts newlines into <br />s + Converts newlines into <br />s. ``linenumbers`` - Displays text with line numbers + Displays text with line numbers. ``ljust`` - Left-aligns the value in a field of a given width + Left-aligns the value in a field of a given width. **Argument:** field size ``lower`` - Converts a string into all lowercase + Converts a string into all lowercase. ``make_list`` Returns the value turned into a list. For an integer, it's a list of digits. For a string, it's a list of characters. ``phone2numeric`` - Takes a phone number and converts it in to its numerical equivalent + Takes a phone number and converts it in to its numerical equivalent. ``pluralize`` - Returns 's' if the value is not 1, for '1 vote' vs. '2 votes' + Returns 's' if the value is not 1, for '1 vote' vs. '2 votes'. ``pprint`` - A wrapper around pprint.pprint -- for debugging, really + A wrapper around pprint.pprint -- for debugging, really. ``random`` - Returns a random item from the list + Returns a random item from the list. ``removetags`` - Removes a space separated list of [X]HTML tags from the output + Removes a space separated list of [X]HTML tags from the output. ``rjust`` - Right-aligns the value in a field of a given width + Right-aligns the value in a field of a given width. **Argument:** field size @@ -696,19 +699,19 @@ Built-in filter reference of Python string formatting ``striptags`` - Strips all [X]HTML tags + Strips all [X]HTML tags. ``time`` Formats a time according to the given format (same as the ``now`` tag). ``timesince`` - Formats a date as the time since that date (i.e. "4 days, 6 hours") + Formats a date as the time since that date (i.e. "4 days, 6 hours"). ``title`` - Converts a string into titlecase + Converts a string into titlecase. ``truncatewords`` - Truncates a string after a certain number of words + Truncates a string after a certain number of words. **Argument:** Number of words to truncate after @@ -733,26 +736,27 @@ Built-in filter reference </li> ``upper`` - Converts a string into all uppercase + Converts a string into all uppercase. ``urlencode`` - Escapes a value for use in a URL + Escapes a value for use in a URL. ``urlize`` - Converts URLs in plain text into clickable links + Converts URLs in plain text into clickable links. ``urlizetrunc`` - Converts URLs into clickable links, truncating URLs to the given character limit + Converts URLs into clickable links, truncating URLs to the given character + limit. - **Argument:** Length to truncate URLs to. + **Argument:** Length to truncate URLs to ``wordcount`` - Returns the number of words + Returns the number of words. ``wordwrap`` - Wraps words at specified line length + Wraps words at specified line length. - **Argument:** number of words to wrap the text at. + **Argument:** number of words at which to wrap the text ``yesno`` Given a string mapping values for true, false and (optionally) None, diff --git a/docs/templates_python.txt b/docs/templates_python.txt index 39b768429b..bd8aea62c7 100644 --- a/docs/templates_python.txt +++ b/docs/templates_python.txt @@ -307,12 +307,12 @@ The Python API Django has two ways to load templates from files: -``django.core.template_loader.get_template(template_name)`` +``django.core.template.loader.get_template(template_name)`` ``get_template`` returns the compiled template (a ``Template`` object) for the template with the given name. If the template doesn't exist, it raises ``django.core.template.TemplateDoesNotExist``. -``django.core.template_loader.select_template(template_name_list)`` +``django.core.template.loader.select_template(template_name_list)`` ``select_template`` is just like ``get_template``, except it takes a list of template names. Of the list, it returns the first template that exists. @@ -398,8 +398,8 @@ Python code, depending on whether you're writing filters or tags. .. admonition:: Behind the scenes For a ton of examples, read the source code for Django's default filters - and tags. They're in ``django/core/defaultfilters.py`` and - ``django/core/defaulttags.py``, respectively. + and tags. They're in ``django/core/template/defaultfilters.py`` and + ``django/core/template/defaulttags.py``, respectively. Writing custom template filters ------------------------------- @@ -710,4 +710,4 @@ The only new concept here is the ``self.nodelist.render(context)`` in For more examples of complex rendering, see the source code for ``{% if %}``, ``{% for %}``, ``{% ifequal %}`` and ``{% ifchanged %}``. They live in -``django/core/defaulttags.py``. +``django/core/template/defaulttags.py``. diff --git a/docs/tutorial03.txt b/docs/tutorial03.txt index 84fb64abfe..f602bf2ebd 100644 --- a/docs/tutorial03.txt +++ b/docs/tutorial03.txt @@ -191,14 +191,13 @@ There's a problem here, though: The page's design is hard-coded in the view. If you want to change the way the page looks, you'll have to edit this Python code. So let's use Django's template system to separate the design from Python:: - from django.core import template_loader - from django.core.template import Context + from django.core.template import Context, loader from django.models.polls import polls from django.utils.httpwrappers import HttpResponse def index(request): latest_poll_list = polls.get_list(order_by=['-pub_date'], limit=5) - t = template_loader.get_template('polls/index') + t = loader.get_template('polls/index') c = Context({ 'latest_poll_list': latest_poll_list, }) @@ -224,7 +223,7 @@ and feel" section of Tutorial 2. When you've done that, create a directory ``polls`` in your template directory. Within that, create a file called ``index.html``. Django requires that templates have ".html" extension. Note that our -``template_loader.get_template('polls/index')`` code from above maps to +``loader.get_template('polls/index')`` code from above maps to "[template_directory]/polls/index.html" on the filesystem. Put the following code in that template:: @@ -256,7 +255,7 @@ provides a shortcut. Here's the full ``index()`` view, rewritten:: latest_poll_list = polls.get_list(order_by=['-pub_date'], limit=5) return render_to_response('polls/index', {'latest_poll_list': latest_poll_list}) -Note that we no longer need to import ``template_loader``, ``Context`` or +Note that we no longer need to import ``loader``, ``Context`` or ``HttpResponse``. The ``render_to_response()`` function takes a template name as its first diff --git a/docs/tutorial04.txt b/docs/tutorial04.txt index 3e6d6205bb..737d8deb1f 100644 --- a/docs/tutorial04.txt +++ b/docs/tutorial04.txt @@ -197,8 +197,8 @@ objects" and "display a detail page for a particular type of object." By default, the ``object_detail`` generic view uses a template called ``<app_label>/<module_name>_detail``. In our case, it'll use the template ``"polls/polls_detail"``. Thus, rename your ``polls/detail.html`` template to -``polls/polls_detail.html``, and change the ``template_loader.get_template()`` -line in ``vote()``. +``polls/polls_detail.html``, and change the ``render_to_response()`` line in +``vote()``. Similarly, the ``object_list`` generic view uses a template called ``<app_label>/<module_name>_list``. Thus, rename ``polls/index.html`` to |
