Por favor, sigue estos estándares de codificación al escribir código para incluirlo en Django.
pre-commit es un marco para gestionar las verificaciones previas a la comitación. Estas verificaciones ayudan a identificar problemas simples antes de comitar el código para revisión. Al comprobar estos problemas antes de la revisión del código permite al revisor centrarse en el cambio en sí mismo, y también puede ayudar a reducir el número de ejecuciones de CI.
Para utilizar la herramienta, primero instala pre-commit y luego las hook de Git:
$ python -m pip install pre-commit
$ pre-commit install
En el primer commit pre-commit instalará las verificaciones, que se instalan en sus propios entornos y tardarán un poco en instalarse al ejecutarse por primera vez. Las comprobaciones posteriores serán significativamente más rápidas. Si se encuentra un error se mostrará un mensaje de error adecuado. Si el error era con black o isort, la herramienta seguirá adelante y los arreglará para ti. Revisa los cambios y reetiqueta para comitar si estás satisfecho con ellos.
Todos los archivos deben estar formateados utilizando el formato automático de black. Esto se ejecutará con pre-commit si está configurado.
El repositorio del proyecto incluye un archivo .editorconfig. Recomendamos utilizar un editor de texto con soporte para EditorConfig para evitar problemas de indentación y espacios en blanco. Los archivos Python utilizan 4 espacios para la indentación y los archivos HTML utilizan 2 espacios.
A menos que se especifique lo contrario, sigue PEP 8.
Usa :pypi:flask8 para comprobar problemas en esta área. Ten en cuenta que nuestro archivo `.flake8` excluye algunos errores que no consideramos como violaciones groseras. Recuerda que PEP 8 es solo una guía, por lo tanto respeta el estilo del código circundante como objetivo principal.
Una excepción a la PEP 8 son nuestras reglas sobre longitudes de línea. No limites las líneas de código a 79 caracteres si eso significa que el código se ve significativamente más feo o es más difícil de leer. Se permite hasta 88 caracteres ya que ésta es la longitud de línea utilizada por black. Esta comprobación está incluida cuando ejecutes flake8. La documentación, los comentarios y las docstrings deben estar envueltos a 79 caracteres, aunque PEP 8 sugiere 72.
La interpolación de variables en cadenas puede utilizar %-formateo , cadenas f o str.format() según sea apropiado, con el objetivo de maximizar la legibilidad del código.
Las sentencias finales sobre la legibilidad quedan a discreción del Merge. Como guía, las cadenas formateadas (f-strings) deben utilizar solo el acceso directo a variables y propiedades simples, con asignación previa de variables locales para casos más complejos:
# Allowed
f"hello {user}"
f"hello {user.name}"
f"hello {self.user.name}"
# Disallowed
f"hello {get_user()}"
f"you are {user.age * 365.25} days old"
# Allowed with local variable assignment
user = get_user()
f"hello {user}"
user_days_old = user.age * 365.25
f"you are {user_days_old} days old"
Las f-strings no deben usarse para ninguna cadena que pueda requerir traducción, incluidos los mensajes de error y de registro. En general, format() es más verboso, por lo que se prefieren otros métodos de formateo.
No desperdicies tiempo haciendo reestructuraciones no relacionadas del código existente para ajustar el método de formato.
Avoid el uso de «nosotros» en comentarios, por ejemplo «Iterar sobre» en lugar de «Nosotros iteramos sobre».
Utiliza subrayados, no camelCase, para nombres de variables, funciones y métodos (es decir poll.get_unique_voters(), no poll.getUniqueVoters()).
Utiliza InitialCaps para nombres de clases (o para funciones de fábrica que devuelven clases).
En las docstrings, sigue el estilo de las docstrings existentes y PEP 257.
En pruebas, utiliza assertRaisesMessage() y assertWarnsMessage() en lugar de assertRaises() y assertWarns() para poder comprobar el mensaje de la excepción o advertencia. Utiliza assertRaisesRegex() y assertWarnsRegex() solo si necesitas coincidencias con expresiones regulares.
Utiliza assertIs(…, True/False) para probar valores booleanos, en lugar de assertTrue() y assertFalse(), para poder comprobar el valor booleano real, no la verdad del expresión.
En las docstrings de pruebas, describe el comportamiento esperado que cada prueba demuestra. No incluyas preámbulos como «Las pruebas que» o «Asegúrate de que».
Reserva las referencias a los tickets para problemas poco comunes donde el ticket tiene detalles adicionales que no se pueden describir fácilmente en las docstrings o comentarios. Incluye el número del ticket al final de una oración como esta:
def test_foo():
"""
A test docstring looks like this (#123456).
"""
...
Donde sea aplicable, utiliza generalizaciones de desempaquetado conforme a PEP 448, como fusionar mapas ({**x, **y}) o secuencias ([*a, *b]). Esto mejora el rendimiento, la legibilidad y la mantenibilidad mientras reduce errores.
Usa :pypi:`isort para automatizar la ordenación de importaciones utilizando las directrices a continuación.
Paso rápido:
$ python -m pip install "isort >= 7.0.0"
$ isort .
Ejecuta isort recursivamente desde tu directorio actual, modificando cualquier archivo que no cumpla con las directrices. Si necesitas tener importaciones fuera del orden (por ejemplo, para evitar un círculo de importación) utiliza un comentario como este:
import module # isort:skip
Coloca las importaciones en estos grupos: futuro, biblioteca estándar, terceras partes, otros componentes Django, componente local Django, try/except. Ordena las líneas en cada grupo alfabéticamente por el nombre del módulo completo. Coloca todas las declaraciones de import module antes de from module import objetos en cada sección. Utiliza importaciones absolutas para otros componentes Django y importaciones relativas para componentes locales.
En cada línea, alfabatiza los elementos con los items mayúscula agrupados antes que los items minúscula.
Rompe líneas largas utilizando paréntesis y dale un indentación de 4 espacios a las líneas de continuación. Incluye una coma final después del último import y coloca el cierre de paréntesis en su propia línea.
Utiliza una sola línea en blanco entre el último import y cualquier código de nivel de módulo, y utiliza dos líneas en blanco sobre la primera función o clase.
Por ejemplo (los comentarios son solo para fines explicativos):
django/contrib/admin/example.py¶# future
from __future__ import unicode_literals
# standard library
import json
from itertools import chain
# third-party
import bcrypt
# Django
from django.http import Http404
from django.http.response import (
Http404,
HttpResponse,
HttpResponseNotAllowed,
StreamingHttpResponse,
cookie,
)
# local Django
from .models import LogEntry
# try/except
try:
import yaml
except ImportError:
yaml = None
CONSTANT = "foo"
class Example: ...
Utiliza importaciones convenientes siempre que estén disponibles. Por ejemplo, haz esto
from django.views import View
En lugar de:
from django.views.generic.base import View
Sigue las siguientes reglas en el código de plantillas Django.
{% extends %} debe ser la primera línea no comentada.
Haz esto:
{% extends "base.html" %}
{% block content %}
<h1 class="font-semibold text-xl">
{{ pages.title }}
</h1>
{% endblock content %}
O esto:
{# This is a comment #}
{% extends "base.html" %}
{% block content %}
<h1 class="font-semibold text-xl">
{{ pages.title }}
</h1>
{% endblock content %}
No hagas esto:
{% load i18n %}
{% extends "base.html" %}
{% block content %}
<h1 class="font-semibold text-xl">
{{ pages.title }}
</h1>
{% endblock content %}
Coloca exactamente un espacio entre {{, contenido de variable y }}.
Haz esto:
{{ user }}
No hagas esto:
{{user}}
En {% load ... %}, enumera las bibliotecas en orden alfabético.
Haz esto:
{% load i18n l10 tz %}
No hagas esto:
{% load l10 i18n tz %}
Coloca exactamente un espacio entre {%, contenido del tag y %}.
Haz esto:
{% load humanize %}
No hagas esto:
{%load humanize%}
Coloca el nombre del tag ` {% block %}` en el tag ` {% endblock %}` si no está en la misma línea.
Haz esto:
{% block header %}
Code goes here
{% endblock header %}
No hagas esto:
{% block header %}
Code goes here
{% endblock %}
Dentro de llaves, separa los tokens con espacios simples, excepto alrededor del . para acceso a atributos y el | para un filtro.
Haz esto:
{% if user.name|lower == "admin" %}
No hagas esto:
{% if user . name | lower == "admin" %}
{{ user.name | upper }}
Dentro de un template que utiliza ` {% extends %}`, evita indentar las etiquetas ` {% block %}` de nivel superior.
Haz esto:
{% extends "base.html" %}
{% block content %}
No hagas esto:
{% extends "base.html" %}
{% block content %}
...
En las vistas Django, el primer parámetro en una función de vista debe llamarse request.
Haz esto:
def my_view(request, foo): ...
No hagas esto:
def my_view(req, foo): ...
Los nombres de campo deben ser todos minúsculos, utilizando guiones bajos en lugar de camelCase.
Haz esto:
class Person(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
No hagas esto:
class Person(models.Model):
FirstName = models.CharField(max_length=20)
Last_Name = models.CharField(max_length=40)
La clase Meta debe aparecer después que se definen los campos, con una sola línea en blanco separando los campos y la definición de la clase.
Haz esto:
class Person(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
class Meta:
verbose_name_plural = "people"
No hagas esto:
class Person(models.Model):
class Meta:
verbose_name_plural = "people"
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=40)
El orden de las clases internas del modelo y los métodos estándar debería ser el siguiente (teniendo en cuenta que estos no son todos obligatorios):
Todos los campos de la base de datos
Atributos de administradores personalizados
class Meta
def __str__()` y otros métodos mágicos de Python`
def save()
def get_absolute_url()
Métodos personalizados
Si está definido choices para un campo de modelo determinado, defina cada elección como una mapeación, con un nombre en mayúsculas que se utilice como atributo de clase del modelo. Ejemplo:
class MyModel(models.Model):
DIRECTION_UP = "U"
DIRECTION_DOWN = "D"
DIRECTION_CHOICES = {
DIRECTION_UP: "Up",
DIRECTION_DOWN: "Down",
}
Alternativamente, considera utilizar :ref:”field-choices-enum-types”.
class MyModel(models.Model):
class Direction(models.TextChoices):
UP = "U", "Up"
DOWN = "D", "Down"
Las módulos no deben utilizar en general las configuraciones almacenadas en django.conf.settings a nivel superior (es decir, evaluadas cuando el módulo se importa). La explicación para esto es la siguiente:
La configuración manual de configuraciones (es decir, no confiando en la variable de entorno DJANGO_SETTINGS_MODULE) está permitida y posible de la siguiente manera:
from django.conf import settings
settings.configure({}, SOME_SETTING="foo")
Sin embargo, si se accede a alguna configuración antes de la línea settings.configure, esto no funcionará. (Internamente, settings es un objeto LazyObject que se configura automáticamente cuando las configuraciones se acceden si aún no ha sido configurado).
Por lo tanto, si hay un módulo que contenga algún código de la siguiente manera:
from django.conf import settings
from django.urls import get_callable
default_foo_view = get_callable(settings.FOO_VIEW)
…entonces importar este módulo causará que el objeto de configuración se configure. Esto significa que la capacidad para que terceros importen el módulo a nivel superior es incompatible con la capacidad de configurar manualmente el objeto de configuración, o lo hace muy difícil en algunas circunstancias.
En lugar del código anterior, debe usarse un nivel de pereza o indirectividad, como django.utils.functional.LazyObject, django.utils.functional.lazy() o lambda.
Marque todas las cadenas para internacionalización; consulte la documentación de i18n para detalles.
Elimine las declaraciones de importación que ya no se utilizan cuando cambie el código. flake8 identificará estas importaciones por ti. Si una importación sin uso necesita permanecer por compatibilidad hacia atrás, marque el final con # NOQA para silenciar la advertencia de flake8.
Quitar sistemáticamente todos los espacios en blanco de fin de línea de tu código ya que estos añaden bytes innecesarios, crean viscosidad visual en las diferencias y pueden causar conflictos de fusión innecesarios. Algunas IDEs pueden configurarse para eliminarlos automáticamente y la mayoría de las herramientas VCS pueden configurarse para destacarlos en los resultados de la diferencia.
No pongas tu nombre en el código que contribuyes. Nuestra política es mantener los nombres de los contribuyentes en el archivo AUTHORS distribuido con Django – no dispersos a lo largo del conjunto de código en sí mismo. Puedes incluir una modificación al archivo AUTHORS en tu parche si haces más de un cambio trivial.
Para obtener detalles sobre el estilo de código JavaScript utilizado por Django, consulte Código JavaScript.
may 31, 2026