{"title":"Filosofía de diseño","version":"5.1","locale":"es","docname":"misc/design-philosophies","url":"/es/5.1/misc/design-philosophies/","canonical":"https://djangodocs.dev/es/5.1/misc/design-philosophies/","summary":"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…","html":"<h1>Filosofía de diseño<a class=\"heading-anchor\" href=\"#design-philosophies\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>This document explains some of the fundamental philosophies Django’s developers\nhave used in creating the framework. Its goal is to explain the past and guide\nthe future.</p>\n<section id=\"overall\">\n<h2>En general<a class=\"heading-anchor\" href=\"#overall\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"loose-coupling\">\n<span id=\"id1\"></span><h3>Bajo acoplamiento<a class=\"heading-anchor\" href=\"#loose-coupling\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p id=\"index-0\">A fundamental goal of Django’s stack is <a class=\"reference external\" href=\"https://wiki.c2.com/?CouplingAndCohesion\">loose coupling and tight cohesion</a>.\nThe various layers of the framework shouldn’t «know» about each other unless\nabsolutely necessary.</p>\n<p>For example, the template system knows nothing about web requests, the database\nlayer knows nothing about data display and the view system doesn’t care which\ntemplate system a programmer uses.</p>\n<p>Although Django comes with a full stack for convenience, the pieces of the\nstack are independent of another wherever possible.</p>\n</section>\n<section id=\"less-code\">\n<span id=\"id2\"></span><h3>Menos código<a class=\"heading-anchor\" href=\"#less-code\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django apps should use as little code as possible; they should lack boilerplate.\nDjango should take full advantage of Python’s dynamic capabilities, such as\nintrospection.</p>\n</section>\n<section id=\"quick-development\">\n<span id=\"id3\"></span><h3>Desarrollo rápido<a class=\"heading-anchor\" href=\"#quick-development\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The point of a web framework in the 21st century is to make the tedious aspects\nof web development fast. Django should allow for incredibly quick web\ndevelopment.</p>\n</section>\n<section id=\"don-t-repeat-yourself-dry\">\n<span id=\"dry\"></span><h3>No te repitas (NTR)<a class=\"heading-anchor\" href=\"#don-t-repeat-yourself-dry\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p id=\"index-1\">Cada concepto distinto y/o dato debe ubicarse en un y sólo un lugar. La redundancia es mala. La normalización es buena.</p>\n<p>The framework, within reason, should deduce as much as possible from as little\nas possible.</p>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">Ver también</p>\n<p>La  <a class=\"reference external\" href=\"https://wiki.c2.com/?DontRepeatYourself\">discusión del principio NTR en el Repositorio Patrón de Portland</a></p>\n</aside>\n</section>\n<section id=\"explicit-is-better-than-implicit\">\n<span id=\"id5\"></span><h3>Explícito es mejor que implícito<a class=\"heading-anchor\" href=\"#explicit-is-better-than-implicit\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>This is a core Python principle listed in <span class=\"target\" id=\"index-2\"></span><a class=\"pep reference external\" href=\"https://peps.python.org/pep-0020/\"><strong>PEP 20</strong></a>, and it means Django\nshouldn’t do too much «magic.» Magic shouldn’t happen unless there’s a really\ngood reason for it. Magic is worth using only if it creates a huge convenience\nunattainable in other ways, and it isn’t implemented in a way that confuses\ndevelopers who are trying to learn how to use the feature.</p>\n</section>\n<section id=\"consistency\">\n<span id=\"id6\"></span><h3>Consistencia<a class=\"heading-anchor\" href=\"#consistency\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The framework should be consistent at all levels. Consistency applies to\neverything from low-level (the Python coding style used) to high-level (the\n«experience» of using Django).</p>\n</section>\n</section>\n<section id=\"models\">\n<h2>Modelos<a class=\"heading-anchor\" href=\"#models\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"id7\">\n<h3>Explícito es mejor que implícito<a class=\"heading-anchor\" href=\"#id7\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Fields shouldn’t assume certain behaviors based solely on the name of the\nfield. This requires too much knowledge of the system and is prone to errors.\nInstead, behaviors should be based on keyword arguments and, in some cases, on\nthe type of the field.</p>\n</section>\n<section id=\"include-all-relevant-domain-logic\">\n<h3>Incluya toda la lógica de dominio relevante<a class=\"heading-anchor\" href=\"#include-all-relevant-domain-logic\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Los modelos deberían encapsular todos los aspectos de un «objeto», siguiendo el  patrón de diseño <a class=\"reference external\" href=\"https://www.martinfowler.com/eaaCatalog/activeRecord.html\">ActiveRecord</a> de Martin Fowler.</p>\n<p>This is why both the data represented by a model and information about\nit (its human-readable name, options like default ordering, etc.) are\ndefined in the model class; all the information needed to understand a\ngiven model should be stored <em>in</em> the model.</p>\n</section>\n</section>\n<section id=\"database-api\">\n<h2>API de base de datos<a class=\"heading-anchor\" href=\"#database-api\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Los objetivos principales de la API de base de datos son:</p>\n<section id=\"sql-efficiency\">\n<h3>La eficiencia de SQL<a class=\"heading-anchor\" href=\"#sql-efficiency\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>It should execute SQL statements as few times as possible, and it should\noptimize statements internally.</p>\n<p>This is why developers need to call <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code> explicitly, rather than the\nframework saving things behind the scenes silently.</p>\n<p>This is also why the <code class=\"docutils literal notranslate\"><span class=\"pre\">select_related()</span></code> <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> method exists. It’s an\noptional performance booster for the common case of selecting «every related\nobject.»</p>\n</section>\n<section id=\"terse-powerful-syntax\">\n<h3>Sintaxis concisa y  potente<a class=\"heading-anchor\" href=\"#terse-powerful-syntax\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The database API should allow rich, expressive statements in as little syntax\nas possible. It should not rely on importing other modules or helper objects.</p>\n<p>Joins should be performed automatically, behind the scenes, when necessary.</p>\n<p>Every object should be able to access every related object, systemwide. This\naccess should work both ways.</p>\n</section>\n<section id=\"option-to-drop-into-raw-sql-easily-when-needed\">\n<h3>Option to drop into raw SQL easily, when needed<a class=\"heading-anchor\" href=\"#option-to-drop-into-raw-sql-easily-when-needed\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The database API should realize it’s a shortcut but not necessarily an\nend-all-be-all. The framework should make it easy to write custom SQL – entire\nstatements, or just custom <code class=\"docutils literal notranslate\"><span class=\"pre\">WHERE</span></code> clauses as custom parameters to API calls.</p>\n</section>\n</section>\n<section id=\"url-design\">\n<h2>Diseño de URLs<a class=\"heading-anchor\" href=\"#url-design\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"id8\">\n<h3>Bajo acoplamiento<a class=\"heading-anchor\" href=\"#id8\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>URLs in a Django app should not be coupled to the underlying Python code. Tying\nURLs to Python function names is a Bad And Ugly Thing.</p>\n<p>Along these lines, the Django URL system should allow URLs for the same app to\nbe different in different contexts. For example, one site may put stories at\n<code class=\"docutils literal notranslate\"><span class=\"pre\">/stories/</span></code>, while another may use <code class=\"docutils literal notranslate\"><span class=\"pre\">/news/</span></code>.</p>\n</section>\n<section id=\"infinite-flexibility\">\n<h3>Flexibilidad infinita<a class=\"heading-anchor\" href=\"#infinite-flexibility\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>URLs should be as flexible as possible. Any conceivable URL design should be\nallowed.</p>\n</section>\n<section id=\"encourage-best-practices\">\n<h3>Fomente las buenas prácticas<a class=\"heading-anchor\" href=\"#encourage-best-practices\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The framework should make it just as easy (or even easier) for a developer to\ndesign pretty URLs than ugly ones.</p>\n<p>File extensions in web-page URLs should be avoided.</p>\n<p>Vignette-style commas in URLs deserve severe punishment.</p>\n</section>\n<section id=\"definitive-urls\">\n<span id=\"id9\"></span><h3>URLs definitivas<a class=\"heading-anchor\" href=\"#definitive-urls\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p id=\"index-3\">Technically, <code class=\"docutils literal notranslate\"><span class=\"pre\">foo.com/bar</span></code> and <code class=\"docutils literal notranslate\"><span class=\"pre\">foo.com/bar/</span></code> are two different URLs, and\nsearch-engine robots (and some web traffic-analyzing tools) would treat them as\nseparate pages. Django should make an effort to «normalize» URLs so that\nsearch-engine robots don’t get confused.</p>\n<p>Este es el razonamiento detrás de la opción :setting: APPEND_SLASH.</p>\n</section>\n</section>\n<section id=\"template-system\">\n<h2>Sistema de plantillas<a class=\"heading-anchor\" href=\"#template-system\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"separate-logic-from-presentation\">\n<span id=\"separation-of-logic-and-presentation\"></span><h3>Separe la lógica de la presentación<a class=\"heading-anchor\" href=\"#separate-logic-from-presentation\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>We see a template system as a tool that controls presentation and\npresentation-related logic – and that’s it. The template system shouldn’t\nsupport functionality that goes beyond this basic goal.</p>\n</section>\n<section id=\"discourage-redundancy\">\n<h3>No promueva la redundancia<a class=\"heading-anchor\" href=\"#discourage-redundancy\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The majority of dynamic websites use some sort of common sitewide design –\na common header, footer, navigation bar, etc. The Django template system should\nmake it easy to store those elements in a single place, eliminating duplicate\ncode.</p>\n<p>This is the philosophy behind <a class=\"reference internal\" href=\"/es/5.1/ref/templates/language/#template-inheritance\"><span class=\"std std-ref\">template inheritance</span></a>.</p>\n</section>\n<section id=\"be-decoupled-from-html\">\n<h3>Be decoupled from HTML<a class=\"heading-anchor\" href=\"#be-decoupled-from-html\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The template system shouldn’t be designed so that it only outputs HTML. It\nshould be equally good at generating other text-based formats, or just plain\ntext.</p>\n</section>\n<section id=\"xml-should-not-be-used-for-template-languages\">\n<h3>XML no se debe utilizar para los lenguajes de plantillas<a class=\"heading-anchor\" href=\"#xml-should-not-be-used-for-template-languages\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p id=\"index-4\">Using an XML engine to parse templates introduces a whole new world of human\nerror in editing templates – and incurs an unacceptable level of overhead in\ntemplate processing.</p>\n</section>\n<section id=\"assume-designer-competence\">\n<h3>Adopte las competencias de diseñador<a class=\"heading-anchor\" href=\"#assume-designer-competence\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The template system shouldn’t be designed so that templates necessarily are\ndisplayed nicely in WYSIWYG editors such as Dreamweaver. That is too severe of\na limitation and wouldn’t allow the syntax to be as nice as it is. Django\nexpects template authors are comfortable editing HTML directly.</p>\n</section>\n<section id=\"treat-whitespace-obviously\">\n<h3>Treat whitespace obviously<a class=\"heading-anchor\" href=\"#treat-whitespace-obviously\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The template system shouldn’t do magic things with whitespace. If a template\nincludes whitespace, the system should treat the whitespace as it treats text\n– just display it. Any whitespace that’s not in a template tag should be\ndisplayed.</p>\n</section>\n<section id=\"don-t-invent-a-programming-language\">\n<h3>No invente un lenguaje de programación<a class=\"heading-anchor\" href=\"#don-t-invent-a-programming-language\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The goal is not to invent a programming language. The goal is to offer just\nenough programming-esque functionality, such as branching and looping, that is\nessential for making presentation-related decisions. The <a class=\"reference internal\" href=\"/es/5.1/topics/templates/#template-language-intro\"><span class=\"std std-ref\">Django Template\nLanguage (DTL)</span></a> aims to avoid advanced logic.</p>\n</section>\n<section id=\"safety-and-security\">\n<h3>Seguridad y protección<a class=\"heading-anchor\" href=\"#safety-and-security\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The template system, out of the box, should forbid the inclusion of malicious\ncode – such as commands that delete database records.</p>\n<p>Esta es otra razón por la que el sistema de plantillas no permite código Python arbitrario.</p>\n</section>\n<section id=\"extensibility\">\n<h3>Extensibilidad<a class=\"heading-anchor\" href=\"#extensibility\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The template system should recognize that advanced template authors may want\nto extend its technology.</p>\n<p>Esta es la filosofía detrás de las etiquetas de plantillas y filtros personalizados.</p>\n</section>\n</section>\n<section id=\"views\">\n<h2>Vistas<a class=\"heading-anchor\" href=\"#views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"simplicity\">\n<h3>Sencillez<a class=\"heading-anchor\" href=\"#simplicity\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Writing a view should be as simple as writing a Python function. Developers\nshouldn’t have to instantiate a class when a function will do.</p>\n</section>\n<section id=\"use-request-objects\">\n<h3>Utilice objetos de petición<a class=\"heading-anchor\" href=\"#use-request-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Views should have access to a request object – an object that stores metadata\nabout the current request. The object should be passed directly to a view\nfunction, rather than the view function having to access the request data from\na global variable. This makes it light, clean and easy to test views by passing\nin «fake» request objects.</p>\n</section>\n<section id=\"id10\">\n<h3>Bajo acoplamiento<a class=\"heading-anchor\" href=\"#id10\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>A view shouldn’t care about which template system the developer uses – or even\nwhether a template system is used at all.</p>\n</section>\n<section id=\"differentiate-between-get-and-post\">\n<h3>Diferencie entre GET y POST<a class=\"heading-anchor\" href=\"#differentiate-between-get-and-post\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>GET and POST are distinct; developers should explicitly use one or the other.\nThe framework should make it easy to distinguish between GET and POST data.</p>\n</section>\n</section>\n<section id=\"cache-framework\">\n<span id=\"cache-design-philosophy\"></span><h2>Framework caché<a class=\"heading-anchor\" href=\"#cache-framework\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Los objetivos centrales del :doc: framework caché de Django &lt;/topics/cache&gt; son:</p>\n<section id=\"id11\">\n<h3>Menos código<a class=\"heading-anchor\" href=\"#id11\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>A cache should be as fast as possible.  Hence, all framework code surrounding\nthe cache backend should be kept to the absolute minimum, especially for\n<code class=\"docutils literal notranslate\"><span class=\"pre\">get()</span></code> operations.</p>\n</section>\n<section id=\"id12\">\n<h3>Consistencia<a class=\"heading-anchor\" href=\"#id12\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The cache API should provide a consistent interface across the different\ncache backends.</p>\n</section>\n<section id=\"id13\">\n<h3>Extensibilidad<a class=\"heading-anchor\" href=\"#id13\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The cache API should be extensible at the application level based on the\ndeveloper’s needs (for example, see <a class=\"reference internal\" href=\"/es/5.1/topics/cache/#cache-key-transformation\"><span class=\"std std-ref\">Cache key transformation</span></a>).</p>\n</section>\n</section>","rootId":"design-philosophies","toc":[{"title":"En general","anchor":"overall","children":[{"title":"Bajo acoplamiento","anchor":"loose-coupling","children":[]},{"title":"Menos código","anchor":"less-code","children":[]},{"title":"Desarrollo rápido","anchor":"quick-development","children":[]},{"title":"No te repitas (NTR)","anchor":"don-t-repeat-yourself-dry","children":[]},{"title":"Explícito es mejor que implícito","anchor":"explicit-is-better-than-implicit","children":[]},{"title":"Consistencia","anchor":"consistency","children":[]}]},{"title":"Modelos","anchor":"models","children":[{"title":"Explícito es mejor que implícito","anchor":"id7","children":[]},{"title":"Incluya toda la lógica de dominio relevante","anchor":"include-all-relevant-domain-logic","children":[]}]},{"title":"API de base de datos","anchor":"database-api","children":[{"title":"La eficiencia de SQL","anchor":"sql-efficiency","children":[]},{"title":"Sintaxis concisa y  potente","anchor":"terse-powerful-syntax","children":[]},{"title":"Option to drop into raw SQL easily, when needed","anchor":"option-to-drop-into-raw-sql-easily-when-needed","children":[]}]},{"title":"Diseño de URLs","anchor":"url-design","children":[{"title":"Bajo acoplamiento","anchor":"id8","children":[]},{"title":"Flexibilidad infinita","anchor":"infinite-flexibility","children":[]},{"title":"Fomente las buenas prácticas","anchor":"encourage-best-practices","children":[]},{"title":"URLs definitivas","anchor":"definitive-urls","children":[]}]},{"title":"Sistema de plantillas","anchor":"template-system","children":[{"title":"Separe la lógica de la presentación","anchor":"separate-logic-from-presentation","children":[]},{"title":"No promueva la redundancia","anchor":"discourage-redundancy","children":[]},{"title":"Be decoupled from HTML","anchor":"be-decoupled-from-html","children":[]},{"title":"XML no se debe utilizar para los lenguajes de plantillas","anchor":"xml-should-not-be-used-for-template-languages","children":[]},{"title":"Adopte las competencias de diseñador","anchor":"assume-designer-competence","children":[]},{"title":"Treat whitespace obviously","anchor":"treat-whitespace-obviously","children":[]},{"title":"No invente un lenguaje de programación","anchor":"don-t-invent-a-programming-language","children":[]},{"title":"Seguridad y protección","anchor":"safety-and-security","children":[]},{"title":"Extensibilidad","anchor":"extensibility","children":[]}]},{"title":"Vistas","anchor":"views","children":[{"title":"Sencillez","anchor":"simplicity","children":[]},{"title":"Utilice objetos de petición","anchor":"use-request-objects","children":[]},{"title":"Bajo acoplamiento","anchor":"id10","children":[]},{"title":"Diferencie entre GET y POST","anchor":"differentiate-between-get-and-post","children":[]}]},{"title":"Framework caché","anchor":"cache-framework","children":[{"title":"Menos código","anchor":"id11","children":[]},{"title":"Consistencia","anchor":"id12","children":[]},{"title":"Extensibilidad","anchor":"id13","children":[]}]}],"breadcrumbs":[{"docname":"misc/index","title":"Documentación meta y miscelánea","url":"/es/5.1/misc/"}],"prev":{"docname":"misc/api-stability","title":"Estabilidad de la API","url":"/es/5.1/misc/api-stability/"},"next":{"docname":"misc/distributions","title":"Distribuciones de terceros de Django","url":"/es/5.1/misc/distributions/"},"formats":{"html":"/es/5.1/misc/design-philosophies/","markdown":"/es/5.1/misc/design-philosophies.md","json":"/es/5.1/misc/design-philosophies.json"},"source":"https://github.com/django/django/blob/stable/5.1.x/docs/misc/design-philosophies.txt","official":"https://docs.djangoproject.com/es/5.1/misc/design-philosophies/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}