{"id":5449,"date":"2018-07-27T13:51:21","date_gmt":"2018-07-27T18:51:21","guid":{"rendered":"https:\/\/islascruz.org\/blog\/?p=5449"},"modified":"2018-08-02T23:47:30","modified_gmt":"2018-08-03T04:47:30","slug":"buenas-practicas-en-django","status":"publish","type":"post","link":"https:\/\/islascruz.org\/blog\/2018\/07\/27\/buenas-practicas-en-django\/","title":{"rendered":"Buenas practicas en Django"},"content":{"rendered":"<p>En un post anterior les coment\u00e9 las buenas pr\u00e1cticas en Python, ahora toca hablar de Django, si bien Django esta hecho en el lenguaje Python tiene sus propias convenciones como framework, y seguir estos lineamientos permitir\u00e1 que tengas proyectos organizados pero sobre todo, que tus compa\u00f1eros de trabajo (si todos siguen estas recomendaciones) y tu funcionen mejor.<\/p>\n<h3>Estilo de c\u00f3digo<\/h3>\n<p>Aqu\u00ed\u00a0no hay mucho que decir, estamos hablando de Python y por lo tanto aplican las reglas de estilo de C\u00f3digo de Python, debes escribir siguiendo la PEP8. Django tambi\u00e9n tiene sus propias convenciones para escribir c\u00f3digo, estas las puedes encontrar <a href=\"https:\/\/docs.djangoproject.com\/en\/2.1\/internals\/contributing\/writing-code\/coding-style\/\" target=\"_blank\" rel=\"noopener\">aqu\u00ed<\/a> , coteja con las de Python, ver\u00e1s que son complementarias.<\/p>\n<h3>Settings<\/h3>\n<p>settings.py es uno de los m\u00f3dulos principales en tu app, en el se definen los par\u00e1metros con los que ha de funcionar tu aplicaci\u00f3n, es importante mantener limpio este m\u00f3dulo, e incluso, quitar lo que no es b\u00e1sico para entender el funcionamiento de la aplicaci\u00f3n o moverlo a otro lado.<\/p>\n<p>Recordemos que estamos hablando de Python, podemos hacer nuestro settings.py muy modular, e importar lo que se necesita en el momento. Por ejemplo, las configuraciones de <code>logging<\/code>\u00a0, o las configuraciones correspondientes al ambiente de desarrollo que son t\u00edpicamente diferentes a las de producci\u00f3n.<\/p>\n<p>Rutas<\/p>\n<p>Nuestro ambiente de desarrollo esta en una ruta en el almacenamiento diferente de la que estar\u00e1 en producci\u00f3n, es por ello que debemos evitar usar rutas &#8220;duras&#8221;, en su lugar debemos referirnos a rutas relativas a una que Python nos proporcionar\u00e1.<\/p>\n<p>Es com\u00fan ver en el settings.py la variable <code>BASE_DIR<\/code>\u00a0y <code>STATIC_ROOT<\/code>\u00a0que son variables donde se define la ruta absoluta del proyecto en disco duro, as\u00ed como donde se guardan los archivos est\u00e1ticos en disco duro. Estas variables las podemos definir mejor as\u00ed:<\/p>\n<pre>BASE_DIR = os.path.dirname(__file__)\nSTATIC_ROOT = os.path.join(BASE_DIR, \"static\")<\/pre>\n<h3>urls<\/h3>\n<p>En nuestro proyecto veremos un archivo <code>urls.py<\/code>\u00a0que no es mas que un m\u00f3dulo que contiene la informaci\u00f3n de cada una e las URLs dentro de nuestro proyecto. Me ha tocado ver urls.py tan largos como la cuaresma, y no, no es nada bonito tener un m\u00f3dulo asi de grande, sobre todo porque es confuso.<\/p>\n<p>Que podemos hacer entonces?. Bueno, en principio, tener un urls.py en cada <code>app<\/code>\u00a0de tu proyecto, de esta forma cada app ser\u00e1 independiente, se reducir\u00e1 el tama\u00f1o del archivo principal y te ser\u00e1 m as f\u00e1cil ubicar las urls en caso de agregar\/editar\/borrar. La otra, en el caso de que nuestra app tenga muchas urls, es modularizar, puedes repartir las urls en mas m\u00f3dulos dependiendo de cada secci\u00f3n dentro de tu app.<\/p>\n<h3>Plantillas<\/h3>\n<p>Las plantillas en Django est\u00e1n en b\u00e1sicamente en dos lugares, en el directorio base de tu proyecto y en el de cada app, ah\u00ed deber\u00e1 haber un directorio llamado <em>templates.<\/em>\u00a0Lo importante aqu\u00ed es que las plantillas de tu app deben estar en el directorio templates dentro de tu app. Las plantillas &#8220;base&#8221; o gen\u00e9ricas podr\u00edan estar en tu directorio templates en el directorio base.<\/p>\n<pre>BASE_DIR\/\n        \/myproject\/\n                  \/settings.py\n                  \/urls.py\n        \/templates\/\n                  \/base.html\n                  \/header.html\n                  \/footer.html\n        \/my_app\/\n               \/models.py\n               \/views.py\n               \/urls.py\n               \/admin.py\n<\/pre>\n<h3>Contenido estatico<\/h3>\n<p>Lo mismo que con las plantillas. Cada app debe mantener su contenido est\u00e1tico para cada una de ellas, con esto mantienes la independencia de la app y permites que pueda ser usada en otros proyectos.<\/p>\n<p>El contenido est\u00e1tico pueden ser:<\/p>\n<ul>\n<li>im\u00e1genes<\/li>\n<li>JavaScript<\/li>\n<li>CSS<\/li>\n<\/ul>\n<p>Ojo, no se debe confundir el contenido est\u00e1tico con el contenido que sube el usuario final, este contenido que sube el usuario va al directorio &#8220;Media&#8221;<\/p>\n<h3>Otras convenciones que aplico yo<\/h3>\n<p>Estas no est\u00e1n dentro de las convenciones de las buenas pr\u00e1cticas en Django, pero las he usado y me han servido muy bien:<\/p>\n<h4>Convertir views.py \/forms.py en un paquete<\/h4>\n<p>Con esto puedo seccionar las partes de mi app, as\u00ed tengo Views para cada secci\u00f3n y son generalmente archivos peque\u00f1os. Con esto evito tener un &#8220;views&#8221; de mas de 1000 lineas.<\/p>\n<pre>BASE_DIR\/\n        \/myproject\/\n        \/my_app\/\n               \/models.py\n               \/urls.py\n               \/admin.py\n               \/views\/\n                     \/customers.py\n                     \/products.py\n                     \/reports.py\n\n<\/pre>\n<h4>Usar siempre Class Views<\/h4>\n<p>Django desde hace buen tiempo ya cuenta con las Class Views. Antes est\u00e1bamos acostumbrados a que cada vista era una funci\u00f3n, pero los Class Views tienen muchas ventajas sobre las funciones.<\/p>\n<p>Lo que mas me gusta es que puedo crear una clase base y solo extender su uso dependiendo de la secci\u00f3n, por ejemplo, tengo la secci\u00f3n Customers, entonces creo una vista b\u00e1sica de &#8220;customers&#8221;:<\/p>\n<pre>class CustomerBasicView(LoginRequiredMixin ,TemplateView):\n    template_name = \"blank.html\"\n    # Esta variable de clase se llenar\u00e1 con el valor delcliente en turno.\n    customer = None\n\n    def get_context_data(self, *args, **kwargs):\n        # Crear el contexto y llenar lo \"General\"\n\n    def get(self, request, *args, **kwargs):\n        # Llamar get_context_data\n        # Llamar una funci\u00f3n en las clases hijas para complementar el contexto\n        # Ejecutar una funci\u00f3n anexa a \"get\" para finalizar get\n        # Si no existe dicha funci\u00f3n retrnar\n        return self.render_to_response(self.context)<\/pre>\n<p>Y las dem\u00e1s clases solo necesitan heredar de <code>CustomerBasicView<\/code><\/p>\n<pre>class Dashboard(CustomerBasicView):\n    template_name=\"customers\/dashboard.html\"\n\nclass View(CustomerBasicVIew):\n    template_name=\"customers\/view.html\"\n\nclass Edit(CusotmerBasicView):\n    template_name=\"customers\/edit.html\"<\/pre>\n<p>Como ven?. Dejar\u00e9 una explicaci\u00f3n mas detallada de esto que hago para otro post. Tal vez ma\u00f1ana.<\/p>\n<hr \/>\n<p>Si te gust\u00f3 el articulo, compartelo en tus redes sociales, si tienes algo que agregar con toda confianza hazlo en los comentarios.<\/p>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_5449\" class=\"pvc_stats all  \" data-element-id=\"5449\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/islascruz.org\/blog\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Aqu\u00ed\u00a0no hay mucho que decir, estamos hablando de Python y por lo tanto aplican las reglas de estilo de C\u00f3digo de Python, debes escribir siguiendo la PEP8. Django tambi\u00e9n tiene sus propias convenciones para escribir c\u00f3digo, estas las puedes encontrar aqu\u00ed , coteja con las de Python, ver\u00e1s que son complementarias.<\/p>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_5449\" class=\"pvc_stats all  \" data-element-id=\"5449\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/islascruz.org\/blog\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"author":1,"featured_media":5439,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14,15,239],"tags":[565,994,16,34,995,993],"class_list":["post-5449","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programming","category-python","category-tips-and-tricks","tag-django","tag-modelos","tag-python-2","tag-tips","tag-trucos","tag-views"],"a3_pvc":{"activated":true,"total_views":14929,"today_views":0},"brizy_media":[],"_links":{"self":[{"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/posts\/5449","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/comments?post=5449"}],"version-history":[{"count":8,"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/posts\/5449\/revisions"}],"predecessor-version":[{"id":5475,"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/posts\/5449\/revisions\/5475"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/media\/5439"}],"wp:attachment":[{"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/media?parent=5449"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/categories?post=5449"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/islascruz.org\/blog\/wp-json\/wp\/v2\/tags?post=5449"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}