Added docs/design_philosophies.txt
git-svn-id: http://code.djangoproject.com/svn/django/trunk@855 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
84a30e7096
commit
5e5fe5b5a2
|
@ -0,0 +1,243 @@
|
|||
===================
|
||||
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 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
|
||||
some level of competence in template authors.
|
||||
|
||||
Treat whitespace obviously
|
||||
--------------------------
|
||||
|
||||
The template system do magic things with whitespace. If a template includes
|
||||
whitespace, the system should treat it 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 are
|
||||
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.
|
Loading…
Reference in New Issue