2
0

design-philosophies.txt 9.8 KB

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