PageRenderTime 232ms CodeModel.GetById 100ms app.highlight 3ms RepoModel.GetById 49ms app.codeStats 0ms

/docs/misc/design-philosophies.txt

https://code.google.com/p/mango-py/
Plain Text | 314 lines | 213 code | 101 blank | 0 comment | 0 complexity | 2178f1b93be39d5a074e6c6cf1d19450 MD5 | raw file
  1===================
  2Design philosophies
  3===================
  4
  5This document explains some of the fundamental philosophies Django's developers
  6have used in creating the framework. Its goal is to explain the past and guide
  7the future.
  8
  9Overall
 10=======
 11
 12.. _loose-coupling:
 13
 14Loose coupling
 15--------------
 16
 17.. index:: coupling; loose
 18
 19A fundamental goal of Django's stack is `loose coupling and tight cohesion`_.
 20The various layers of the framework shouldn't "know" about each other unless
 21absolutely necessary.
 22
 23For example, the template system knows nothing about Web requests, the database
 24layer knows nothing about data display and the view system doesn't care which
 25template system a programmer uses.
 26
 27Although Django comes with a full stack for convenience, the pieces of the
 28stack are independent of another wherever possible.
 29
 30.. _`loose coupling and tight cohesion`: http://c2.com/cgi/wiki?CouplingAndCohesion
 31
 32.. _less-code:
 33
 34Less code
 35---------
 36
 37Django apps should use as little code as possible; they should lack boilerplate.
 38Django should take full advantage of Python's dynamic capabilities, such as
 39introspection.
 40
 41.. _quick-development:
 42
 43Quick development
 44-----------------
 45
 46The point of a Web framework in the 21st century is to make the tedious aspects
 47of Web development fast. Django should allow for incredibly quick Web
 48development.
 49
 50.. _dry:
 51
 52Don't repeat yourself (DRY)
 53---------------------------
 54
 55.. index::
 56   single: DRY
 57   single: Don't repeat yourself
 58
 59Every distinct concept and/or piece of data should live in one, and only one,
 60place. Redundancy is bad. Normalization is good.
 61
 62The framework, within reason, should deduce as much as possible from as little
 63as possible.
 64
 65.. seealso::
 66
 67    The `discussion of DRY on the Portland Pattern Repository`__
 68
 69    __ http://c2.com/cgi/wiki?DontRepeatYourself
 70    
 71.. _explicit-is-better-than-implicit:
 72
 73Explicit is better than implicit
 74--------------------------------
 75
 76This, a `core Python principle`_, means Django shouldn't do too much "magic."
 77Magic shouldn't happen unless there's a really good reason for it. Magic is
 78worth using only if it creates a huge convenience unattainable in other ways,
 79and it isn't implemented in a way that confuses developers who are trying to
 80learn how to use the feature.
 81
 82.. _`core Python principle`: http://www.python.org/dev/peps/pep-0020/
 83
 84.. _consistency:
 85
 86Consistency
 87-----------
 88
 89The framework should be consistent at all levels. Consistency applies to
 90everything from low-level (the Python coding style used) to high-level (the
 91"experience" of using Django).
 92
 93Models
 94======
 95
 96Explicit is better than implicit
 97--------------------------------
 98
 99Fields shouldn't assume certain behaviors based solely on the name of the
100field. This requires too much knowledge of the system and is prone to errors.
101Instead, behaviors should be based on keyword arguments and, in some cases, on
102the type of the field.
103
104Include all relevant domain logic
105---------------------------------
106
107Models should encapsulate every aspect of an "object," following Martin
108Fowler's `Active Record`_ design pattern.
109
110This is why both the data represented by a model and information about
111it (its human-readable name, options like default ordering, etc.) are
112defined in the model class; all the information needed to understand a
113given model should be stored *in* the model.
114
115.. _`Active Record`: http://www.martinfowler.com/eaaCatalog/activeRecord.html
116
117Database API
118============
119
120The core goals of the database API are:
121
122SQL efficiency
123--------------
124
125It should execute SQL statements as few times as possible, and it should
126optimize statements internally.
127
128This is why developers need to call ``save()`` explicitly, rather than the
129framework saving things behind the scenes silently.
130
131This is also why the ``select_related()`` ``QuerySet`` method exists. It's an
132optional performance booster for the common case of selecting "every related
133object."
134
135Terse, powerful syntax
136----------------------
137
138The database API should allow rich, expressive statements in as little syntax
139as possible. It should not rely on importing other modules or helper objects.
140
141Joins should be performed automatically, behind the scenes, when necessary.
142
143Every object should be able to access every related object, systemwide. This
144access should work both ways.
145
146Option to drop into raw SQL easily, when needed
147-----------------------------------------------
148
149The database API should realize it's a shortcut but not necessarily an
150end-all-be-all. The framework should make it easy to write custom SQL -- entire
151statements, or just custom ``WHERE`` clauses as custom parameters to API calls.
152
153URL design
154==========
155
156Loose coupling
157--------------
158
159URLs in a Django app should not be coupled to the underlying Python code. Tying
160URLs to Python function names is a Bad And Ugly Thing.
161
162Along these lines, the Django URL system should allow URLs for the same app to
163be different in different contexts. For example, one site may put stories at
164``/stories/``, while another may use ``/news/``.
165
166Infinite flexibility
167--------------------
168
169URLs should be as flexible as possible. Any conceivable URL design should be
170allowed.
171
172Encourage best practices
173------------------------
174
175The framework should make it just as easy (or even easier) for a developer to
176design pretty URLs than ugly ones.
177
178File extensions in Web-page URLs should be avoided.
179
180Vignette-style commas in URLs deserve severe punishment.
181
182.. _definitive-urls:
183
184Definitive URLs
185---------------
186
187.. index:: urls; definitive
188
189Technically, ``foo.com/bar`` and ``foo.com/bar/`` are two different URLs, and
190search-engine robots (and some Web traffic-analyzing tools) would treat them as
191separate pages. Django should make an effort to "normalize" URLs so that
192search-engine robots don't get confused.
193
194This is the reasoning behind the :setting:`APPEND_SLASH` setting.
195
196Template system
197===============
198
199.. _separation-of-logic-and-presentation:
200
201Separate logic from presentation
202--------------------------------
203
204We see a template system as a tool that controls presentation and
205presentation-related logic -- and that's it. The template system shouldn't
206support functionality that goes beyond this basic goal.
207
208If we wanted to put everything in templates, we'd be using PHP. Been there,
209done that, wised up.
210
211Discourage redundancy
212---------------------
213
214The majority of dynamic Web sites use some sort of common sitewide design --
215a common header, footer, navigation bar, etc. The Django template system should
216make it easy to store those elements in a single place, eliminating duplicate
217code.
218
219This is the philosophy behind :ref:`template inheritance
220<template-inheritance>`.
221
222Be decoupled from HTML
223----------------------
224
225The template system shouldn't be designed so that it only outputs HTML. It
226should be equally good at generating other text-based formats, or just plain
227text.
228
229XML should not be used for template languages
230---------------------------------------------
231
232.. index:: xml; suckiness of
233
234Using an XML engine to parse templates introduces a whole new world of human
235error in editing templates -- and incurs an unacceptable level of overhead in
236template processing.
237
238Assume designer competence
239--------------------------
240
241The template system shouldn't be designed so that templates necessarily are
242displayed nicely in WYSIWYG editors such as Dreamweaver. That is too severe of
243a limitation and wouldn't allow the syntax to be as nice as it is. Django
244expects template authors are comfortable editing HTML directly.
245
246Treat whitespace obviously
247--------------------------
248
249The template system shouldn't do magic things with whitespace. If a template
250includes whitespace, the system should treat the whitespace as it treats text
251-- just display it. Any whitespace that's not in a template tag should be
252displayed.
253
254Don't invent a programming language
255-----------------------------------
256
257The template system intentionally doesn't allow the following:
258
259    * Assignment to variables
260    * Advanced logic
261
262The goal is not to invent a programming language. The goal is to offer just
263enough programming-esque functionality, such as branching and looping, that is
264essential for making presentation-related decisions.
265
266The Django template system recognizes that templates are most often written by
267*designers*, not *programmers*, and therefore should not assume Python
268knowledge.
269
270Safety and security
271-------------------
272
273The template system, out of the box, should forbid the inclusion of malicious
274code -- such as commands that delete database records.
275
276This is another reason the template system doesn't allow arbitrary Python code.
277
278Extensibility
279-------------
280
281The template system should recognize that advanced template authors may want
282to extend its technology.
283
284This is the philosophy behind custom template tags and filters.
285
286Views
287=====
288
289Simplicity
290----------
291
292Writing a view should be as simple as writing a Python function. Developers
293shouldn't have to instantiate a class when a function will do.
294
295Use request objects
296-------------------
297
298Views should have access to a request object -- an object that stores metadata
299about the current request. The object should be passed directly to a view
300function, rather than the view function having to access the request data from
301a global variable. This makes it light, clean and easy to test views by passing
302in "fake" request objects.
303
304Loose coupling
305--------------
306
307A view shouldn't care about which template system the developer uses -- or even
308whether a template system is used at all.
309
310Differentiate between GET and POST
311----------------------------------
312
313GET and POST are distinct; developers should explicitly use one or the other.
314The framework should make it easy to distinguish between GET and POST data.