{"title":"Escribiendo tu primer parche para Django","version":"1.11","locale":"es","docname":"intro/contributing","url":"/es/1.11/intro/contributing/","canonical":"https://djangodocs.dev/es/1.11/intro/contributing/","summary":"Introducción Link to this heading # ¿Interesado en dar un poco a la comunidad? Quizás ha encontrado un bug en Django que le gustaría ver solucionado, o quizás hay…","html":"<h1>Escribiendo tu primer parche para Django<a class=\"heading-anchor\" href=\"#writing-your-first-patch-for-django\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<section id=\"introduction\">\n<h2>Introducción<a class=\"heading-anchor\" href=\"#introduction\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>¿Interesado en dar un poco a la comunidad? Quizás ha encontrado un bug en Django que le gustaría ver solucionado, o quizás hay una pequeña característica que quiera agregar.</p>\n<p>Contribuir con Django en sí es la mejor forma de ver abordadas tus propias inquietudes. Esto puede parecer intimidante al principio, pero en realidad es bastante simple. Te guiaremos a través de todo el proceso para que puedas aprender mediante ejemplos.</p>\n<section id=\"who-s-this-tutorial-for\">\n<h3>¿Para quién es este tutorial?<a class=\"heading-anchor\" href=\"#who-s-this-tutorial-for\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">Ver también</p>\n<p>Si usted está buscando una referencia sobre cómo presentar parches, consulte la documentación <a class=\"reference internal\" href=\"/es/1.11/internals/contributing/writing-code/submitting-patches/\"><span class=\"doc\">Submitting patches</span></a>.</p>\n</aside>\n<p>Para este tutorial, esperamos que comprenda al menos el funcionamiento básico de Django. Esto significa que usted no tendría problemas estudiando los tutoriales existentes para <a class=\"reference internal\" href=\"/es/1.11/intro/tutorial01/\"><span class=\"doc\">crear su primera aplicación Django</span></a>. Adicionalmente, debería tener una buena comprensión de Python. Si no es así, <a href=\"#id14\"><span class=\"problematic\" id=\"id15\">`Dive into Python`__</span></a> es un libro fantástico (y gratuito) disponible en línea para los programadores que comienzan en Python.</p>\n<p>Aquellos de ustedes que no están familiarizados con los sistemas de control de versiones y Trac encontrarán que este tutorial y sus vínculos incluyen información suficiente para empezar. Sin embargo, es probable que quiera leer un poco más acerca de estas diferentes herramientas si usted planea contribuir a Django con regularidad.</p>\n<p>Sin embargo, en su mayor parte, este tutorial trata de explicar tanto como sea posible, de modo que pueda ser de utilidad para la audiencia más amplia.</p>\n<aside class=\"admonition-where-to-get-help admonition\">\n<p class=\"admonition-title\">Dónde obtener ayuda:</p>\n<p>Si presentas problemas leyendo este tutorial, por favor envíe un mensaje a <a class=\"reference internal\" href=\"/es/1.11/internals/mailing-lists/#django-developers-mailing-list\"><span class=\"std std-ref\">django-developers</span></a> o visita <a href=\"#id14\"><span class=\"problematic\" id=\"id16\">`#django-dev en irc.freenode.net`__</span></a> para chatear con otros usuarios de Django que podrían ayudarte.</p>\n</aside>\n</section>\n<section id=\"what-does-this-tutorial-cover\">\n<h3>¿Qué cubre esta guía?<a class=\"heading-anchor\" href=\"#what-does-this-tutorial-cover\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Te mostraremos cómo contribuir con parches para Django por primera vez. Al final de este tutorial, contará con un entendimiento básico sobre las herramientas y procesos implicados. Específicamente, cubriremos lo siguiente:</p>\n<ul class=\"simple\">\n<li><p>Instalando Git.</p></li>\n<li><p>Cómo descargar una copia de desarrollo de Django.</p></li>\n<li><p>Conjunto de pruebas de funcionamiento de Django.</p></li>\n<li><p>Escribiendo una prueba para su parche.</p></li>\n<li><p>Escribiendo el código para su parche.</p></li>\n<li><p>Probando su parche.</p></li>\n<li><p>Submitting a pull request.</p></li>\n<li><p>Dónde buscar más información.</p></li>\n</ul>\n<p>Una vez que haya terminado el tutorial, puede revisar el resto de <a class=\"reference internal\" href=\"/es/1.11/internals/contributing/\"><span class=\"doc\">la documentación para contribuir con Django</span></a>. Contiene una gran cantidad de información de lectura obligatoria para todo el que desee convertirse en colaborador habitual de Django. Si tiene preguntas, es probable que obtenga las respuestas.</p>\n<aside class=\"admonition-python-3-required admonition\">\n<p class=\"admonition-title\">¡se requiere Python 3!</p>\n<p>This tutorial assumes you are using Python 3. Get the latest version at\n<a class=\"reference external\" href=\"https://www.python.org/downloads/\">Python’s download page</a> or with your\noperating system’s package manager.</p>\n</aside>\n<aside class=\"admonition-for-windows-users admonition\">\n<p class=\"admonition-title\">Para los usuarios de Windows</p>\n<p>Al instalar Python en Windows, asegúrese de revisar la opción «Añadir python.exe a la Ruta», de modo que que siempre esté disponible en la línea de comandos.</p>\n</aside>\n</section>\n</section>\n<section id=\"code-of-conduct\">\n<h2>Código de Conducta<a class=\"heading-anchor\" href=\"#code-of-conduct\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Como un colaborador, usted puede ayudarnos a mantener abierta e inclusiva la comunidad Django. Por favor lea y siga nuestro <a class=\"reference external\" href=\"https://www.djangoproject.com/conduct/\">Código de conducta</a>.</p>\n</section>\n<section id=\"installing-git\">\n<h2>Instalando Git<a class=\"heading-anchor\" href=\"#installing-git\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Para este tutorial, necesitará instalar Git para descargar la versión actual de desarrollo de Django y generar archivos de revisión de los cambios que realice.</p>\n<p>Para revisar si tiene o no instalado Git , ejecute <code class=\"docutils literal notranslate\"><span class=\"pre\">git</span></code> en la línea de comandos. Si recibe un mensaje diciendo que el comando no pudo ser encontrado, tendrá que descargarlo e instalarlo, consulte <a href=\"#id14\"><span class=\"problematic\" id=\"id17\">`la página de descarga de Git`__</span></a>.</p>\n<aside class=\"admonition-for-windows-users admonition\">\n<p class=\"admonition-title\">Para los usuarios de Windows</p>\n<p>Al instalar Git en Windows, se recomienda que usted seleccione la opción «Git Bash» para que Git se ejecute en su propia shell. Este tutorial asume que usted lo ha instalado de esa forma.</p>\n</aside>\n<p>Si no estás familiarizado con Git, siempre se puede encontrar más información sobre sus comandos (una vez instalado) escribiendo <code class=\"docutils literal notranslate\"><span class=\"pre\">git</span> <span class=\"pre\">help</span></code> en la línea de comandos.</p>\n</section>\n<section id=\"getting-a-copy-of-django-s-development-version\">\n<h2>Obtener una copia de la versión de desarrollo de Django<a class=\"heading-anchor\" href=\"#getting-a-copy-of-django-s-development-version\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>The first step to contributing to Django is to get a copy of the source code.\nFirst, <a class=\"reference external\" href=\"https://github.com/django/django/fork\">fork Django on GitHub</a>. Then,\nfrom the command line, use the <code class=\"docutils literal notranslate\"><span class=\"pre\">cd</span></code> command to navigate to the directory\nwhere you’ll want your local copy of Django to live.</p>\n<p>Descargue el repositorio de código fuente de Django con el siguiente comando:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>git<span class=\"w\"> </span>clone<span class=\"w\"> </span>git@github.com:YourGitHubName/django.git\n</code></pre></div>\n<p>Ahora que usted tiene una copia local de Django, puede instalarla como instalaría cualquier paquete utilizando <code class=\"docutils literal notranslate\"><span class=\"pre\">pip</span></code>. La forma más conveniente de hacerlo es mediante la utilización de un <em>entorno virtual</em> (o virtualenv) que es una característica integrada en Python que permite mantener un directorio independiente de los paquetes instalados para cada uno de sus proyectos para que no interfieran entre sí.</p>\n<p>Es una buena idea guardar todos sus entornos virtuales en un lugar, por ejemplo, en <code class=\"docutils literal notranslate\"><span class=\"pre\">.virtualenvs/</span></code> en su directorio principal. Créelo si todavía no existe:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>mkdir<span class=\"w\"> </span>~/.virtualenvs\n</code></pre></div>\n<p>Ahora cree un nuevo virtualenv ejecutando:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>python3<span class=\"w\"> </span>-m<span class=\"w\"> </span>venv<span class=\"w\"> </span>~/.virtualenvs/djangodev\n</code></pre></div>\n<p>La ruta es donde se guardará el nuevo entorno en su computadora.</p>\n<aside class=\"admonition-for-windows-users admonition\">\n<p class=\"admonition-title\">Para los usuarios de Windows</p>\n<p>Utilizar el módulo incorporado <code class=\"docutils literal notranslate\"><span class=\"pre\">venv</span></code> no funcionará si también está usando el Git Bash shell en Windows, ya que los scripts de activación se crean sólo para el shell del sistema (<code class=\"docutils literal notranslate\"><span class=\"pre\">.bat</span></code>) y PowerShell (<code class=\"docutils literal notranslate\"><span class=\"pre\">.ps1</span></code>). Utilice en cambio el paquete <code class=\"docutils literal notranslate\"><span class=\"pre\">virtualenv</span></code>:</p>\n<div class=\"code-block\" data-language=\"none\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">None</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"None code\"><code>$ pip install virtualenv\n$ virtualenv ~/.virtualenvs/djangodev\n</code></pre></div>\n</aside>\n<aside class=\"admonition-for-ubuntu-users admonition\">\n<p class=\"admonition-title\">Para los usuarios de Ubuntu</p>\n<p>En algunas versiones de Ubuntu el comando anterior podría fallar. Utilice en cambio el paquete <code class=\"docutils literal notranslate\"><span class=\"pre\">virtualenv</span></code>, primero asegúrese de que tiene <code class=\"docutils literal notranslate\"><span class=\"pre\">pip3</span></code>:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>sudo<span class=\"w\"> </span>apt-get<span class=\"w\"> </span>install<span class=\"w\"> </span>python3-pip\n<span class=\"gp\">$ </span><span class=\"c1\"># Prefix the next command with sudo if it gives a permission denied error</span>\n<span class=\"gp\">$ </span>pip3<span class=\"w\"> </span>install<span class=\"w\"> </span>virtualenv\n<span class=\"gp\">$ </span>virtualenv<span class=\"w\"> </span>--python<span class=\"o\">=</span><span class=\"sb\">`</span>which<span class=\"w\"> </span>python3<span class=\"sb\">`</span><span class=\"w\"> </span>~/.virtualenvs/djangodev\n</code></pre></div>\n</aside>\n<p>El último paso para instalar su virtualenv es activarlo:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span><span class=\"nb\">source</span><span class=\"w\"> </span>~/.virtualenvs/djangodev/bin/activate\n</code></pre></div>\n<p>Si el comando <code class=\"docutils literal notranslate\"><span class=\"pre\">source</span></code> no está disponible, puede intentar usar un punto en su lugar:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>.<span class=\"w\"> </span>~/.virtualenvs/djangodev/bin/activate\n</code></pre></div>\n<aside class=\"admonition-for-windows-users admonition\">\n<p class=\"admonition-title\">Para los usuarios de Windows</p>\n<p>Para activar su virtualenv en Windows, ejecute:</p>\n<div class=\"code-block\" data-language=\"none\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">None</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"None code\"><code>$ source ~/virtualenvs/djangodev/Scripts/activate\n</code></pre></div>\n</aside>\n<p>Tiene que activar el virtualenv cada vez que abre una nueva ventana de terminal. virtualenvwrapper es una herramienta útil para hacer esto más fácil.</p>\n<p>Todo lo que usted instala a través de <code class=\"docutils literal notranslate\"><span class=\"pre\">pip</span></code> a partir de ahora será instalado en su nuevo virtualenv, aislado de otros entornos y paquetes de todo el sistema. Además, el nombre del virtualenv actualmente activado se muestra en la línea de comandos para ayudarle a saber cuál está utilizando. Continúe e instale la copia de Django previamente clonada:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>pip<span class=\"w\"> </span>install<span class=\"w\"> </span>-e<span class=\"w\"> </span>/path/to/your/local/clone/django/\n</code></pre></div>\n<p>La versión instalada de Django está señalando su copia local. Inmediatamente verá los cambios que le realice a la misma, lo cual será de gran ayuda cuando escriba su primer parche.</p>\n</section>\n<section id=\"rolling-back-to-a-previous-revision-of-django\">\n<h2>Restaurar una versión previa de Django<a class=\"heading-anchor\" href=\"#rolling-back-to-a-previous-revision-of-django\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Para este tutorial, vamos a utilizar el ticket: ticket:24788 como caso de estudio, por lo que vamos a rebobinar el historial de versiones de Django en git hasta antes de que se aplicara el parche de dicho ticket. Esto nos permitirá revisar todos los pasos necesarios para escribir ese parche desde cero, incluyendo la ejecución del conjunto de pruebas de Django.</p>\n<p><strong>Recuerde que aunque estaremos usando una revisión anterior del repositorio central de Django para los propósitos del tutorial a continuación, ¡Usted siempre debería usar la revisión actual de desarrollo de Django cuando trabaje en su propio parche para un ticket!</strong></p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Nota</p>\n<p>El parche para este ticket fue escrito por Paweł Marczewski, y se aplicó a Django como <a href=\"#id14\"><span class=\"problematic\" id=\"id18\">`commit 4df7e8483b2679fc1cba3410f08960bac6f51115`__</span></a>. Por lo tanto, estaremos utilizando la revisión de Django inmediatamente anterior a ese, <a href=\"#id14\"><span class=\"problematic\" id=\"id19\">`commit 4ccfc4439a7add24f8db4ef3960d02ef8ae09887`__</span></a>.</p>\n</aside>\n<p>Navegue en el directorio raíz de Django (es el único que contiene <code class=\"docutils literal notranslate\"><span class=\"pre\">django</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">docs</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">tests</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">AUTHORS</span></code>, etc.). Usted puede después ver la revisión anterior de Django que estaremos utilizando en el tutorial a continuación:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>git<span class=\"w\"> </span>checkout<span class=\"w\"> </span>4ccfc4439a7add24f8db4ef3960d02ef8ae09887\n</code></pre></div>\n</section>\n<section id=\"running-django-s-test-suite-for-the-first-time\">\n<h2>Ejecutando el conjunto de pruebas de Django por primera vez<a class=\"heading-anchor\" href=\"#running-django-s-test-suite-for-the-first-time\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Al contribuir con Django es muy importante que las modificaciones de su código no introduzcan bugs en otras áreas de Django. Una manera de comprobar que Django todavía funciona después de que usted realice las modificaciones es ejecutar el conjunto de pruebas de Django. Si todavía todas las pruebas pasan, entonces usted puede estar razonablemente seguro de que sus modificaciones no descompusieron por completo a Django. Si usted nunca antes ha ejecutado el conjunto de pruebas de Django, es una buena idea ejecutarlas una vez con anterioridad para familiarizarse con lo que se supone sería su resultado.</p>\n<p>Antes de ejecutar el conjunto de pruebas, instale sus dependencias, primero cambiándo al directorio <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/</span></code> de Django y después ejecutando:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>pip<span class=\"w\"> </span>install<span class=\"w\"> </span>-r<span class=\"w\"> </span>requirements/py3.txt\n</code></pre></div>\n<p>If you encounter an error during the installation, your system might be missing\na dependency for one or more of the Python packages. Consult the failing\npackage’s documentation or search the Web with the error message that you\nencounter.</p>\n<p>Now we are ready to run the test suite. If you’re using GNU/Linux, macOS, or\nsome other flavor of Unix, run:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>./runtests.py\n</code></pre></div>\n<p>Ahora siéntese y relájese. Todo el conjunto de pruebas de Django tiene más de 9.600 pruebas diferentes, por lo que puede tomar de 5 a 15 minutos para ejecutarse, dependiendo de la velocidad de su computadora.</p>\n<p>Mientras que el conjunto de pruebas de Django se esté ejecutando, usted verá una cadena de caracteres que representa el estado de cada prueba mientras se ejecuta. La <code class=\"docutils literal notranslate\"><span class=\"pre\">E</span></code> indica que se produjo un error durante una prueba, y la <code class=\"docutils literal notranslate\"><span class=\"pre\">F</span></code> indica que los asertos de una prueba fallaron. Ambos se consideran errores de pruebas. Mientras tanto, la <code class=\"docutils literal notranslate\"><span class=\"pre\">x</span></code> y la <code class=\"docutils literal notranslate\"><span class=\"pre\">s</span></code> indican errores esperados y pruebas omitidas respectivamente. Los puntos indican las pruebas aprobadas.</p>\n<p>Skipped tests are typically due to missing external libraries required to run\nthe test; see <a class=\"reference internal\" href=\"/es/1.11/internals/contributing/writing-code/unit-tests/#running-unit-tests-dependencies\"><span class=\"std std-ref\">Running all the tests</span></a> for a list of dependencies\nand be sure to install any for tests related to the changes you are making (we\nwon’t need any for this tutorial). Some tests are specific to a particular\ndatabase backend and will be skipped if not testing with that backend. SQLite\nis the database backend for the default settings. To run the tests using a\ndifferent backend, see <a class=\"reference internal\" href=\"/es/1.11/internals/contributing/writing-code/unit-tests/#running-unit-tests-settings\"><span class=\"std std-ref\">Using another settings module</span></a>.</p>\n<p>Once the tests complete, you should be greeted with a message informing you\nwhether the test suite passed or failed. Since you haven’t yet made any changes\nto Django’s code, the entire test suite <strong>should</strong> pass. If you get failures or\nerrors make sure you’ve followed all of the previous steps properly. See\n<a class=\"reference internal\" href=\"/es/1.11/internals/contributing/writing-code/unit-tests/#running-unit-tests\"><span class=\"std std-ref\">Running the unit tests</span></a> for more information. If you’re using Python 3.5+,\nthere will be a couple failures related to deprecation warnings that you can\nignore. These failures have since been fixed in Django.</p>\n<p>Tenga en cuenta que el último trunk de Django no siempre puede ser estable. Cuando se desarrolla sobre trunk se pueden verificar <a href=\"#id14\"><span class=\"problematic\" id=\"id20\">`las construcciones de integración continuas de Django`__</span></a> para determinar si las fallas son específicas de su computadora o si también están presentes en las builds oficiales de Django. Si hace clic para ver una build en particular, usted puede ver la «Matriz de configuración», que muestra los fallos analizados por la versión de Python y el backend de la base de datos.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Nota</p>\n<p>Para este tutorial y el ticket en el que estamos trabajando, es suficiente probar contra SQLite, sin embargo, es posible (y a veces necesario) <a class=\"reference internal\" href=\"/es/1.11/internals/contributing/writing-code/unit-tests/#running-unit-tests-settings\"><span class=\"std std-ref\">ejecutar las pruebas utilizando una base de datos diferente</span></a>.</p>\n</aside>\n</section>\n<section id=\"creating-a-branch-for-your-patch\">\n<h2>Creating a branch for your patch<a class=\"heading-anchor\" href=\"#creating-a-branch-for-your-patch\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Before making any changes, create a new branch for the ticket:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>git<span class=\"w\"> </span>checkout<span class=\"w\"> </span>-b<span class=\"w\"> </span>ticket_24788\n</code></pre></div>\n<p>You can choose any name that you want for the branch, «ticket_24788» is an\nexample. All changes made in this branch will be specific to the ticket and\nwon’t affect the main copy of the code that we cloned earlier.</p>\n</section>\n<section id=\"writing-some-tests-for-your-ticket\">\n<h2>Escribiendo algunas pruebas para su reporte<a class=\"heading-anchor\" href=\"#writing-some-tests-for-your-ticket\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>En la mayoría de los casos, para que un parche sea aceptado en Django tiene que incluir pruebas. Para los parches de corrección de bugs, esto significa escribir una prueba de regresión para asegurar que el bug no sea reintroducido en Django más adelante. Una prueba de regresión debe ser escrita de forma tal que falle mientras que todavía exista el bug y pase una vez que el bug se haya corregido. Para los parches que contienen nuevas características, tendrás que incluir pruebas que garanticen que dichas características estén funcionando correctamente. Los parches también deben fallar cuando la nueva característica no esté presente y por lo tanto, pasar una vez que haya sido aplicada.</p>\n<p>Una buena forma de hacer esto, es escribir primero sus nuevas pruebas antes de realizar cualquier cambio en el código. Este estilo de desarrollo se llama <a href=\"#id14\"><span class=\"problematic\" id=\"id21\">`desarrollo guiado por pruebas`__</span></a> y se puede aplicar tanto a proyectos completos como a parches individuales. Después de escribir sus pruebas, ejecútelas para asegurarse de que en efecto fallan (ya que aún no ha corregido ese bug o añadido esa característica). Si sus nuevas pruebas no fallan, tendrá que arreglarlas de manera que lo hagan. Después de todo, una prueba de regresión que pasa sin importar si un error está presente, no es muy útil en prevenir que ese error se repita en el futuro.</p>\n<p>Ahora a nuestro ejemplo práctico.</p>\n<section id=\"writing-some-tests-for-ticket-24788\">\n<h3>Escribiendo algunas pruebas para el ticket #24788<a class=\"heading-anchor\" href=\"#writing-some-tests-for-ticket-24788\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Ticket <a class=\"extlink-ticket reference external\" href=\"https://code.djangoproject.com/ticket/24788\">#24788</a> propone una pequeña adición de característica: la capacidad para especificar el atributo de nivel de la clase <code class=\"docutils literal notranslate\"><span class=\"pre\">prefix</span></code> en las clases de formularios, de modo que:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>[…] forms which ship with apps could effectively namespace themselves such\nthat N overlapping form fields could be POSTed at once and resolved to the\ncorrect form.\n</code></pre></div>\n<p>Para resolver este ticket, vamos a añadir un atributo <code class=\"docutils literal notranslate\"><span class=\"pre\">prefix</span></code> a la clase <code class=\"docutils literal notranslate\"><span class=\"pre\">BaseForm</span></code>. Cuando se crean instancias de esta clase, pasar un prefijo al método <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__()</span></code> todavía asignará ese prefijo en la instancia creada. Sin embargo, no pasar un prefijo ( o pasar <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>) usará el prefijo de nivel de clase. No obstante, antes de realizar esas modificaciones, vamos a escribir varias pruebas para comprobar que nuestra modificación funciona correctamente y seguirá funcionando en el futuro.</p>\n<p>Navegue a la carpeta <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/forms_tests/tests/</span></code> de Django y abra el archivo <code class=\"docutils literal notranslate\"><span class=\"pre\">test_forms.py</span></code>. Agregue el siguiente código en la línea 1674 antes de la función <code class=\"docutils literal notranslate\"><span class=\"pre\">test_forms_with_null_boolean</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_class_prefix</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Prefix can be also specified at the class level.</span>\n    <span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Person</span><span class=\"p\">(</span><span class=\"n\">Form</span><span class=\"p\">):</span>\n        <span class=\"n\">first_name</span> <span class=\"o\">=</span> <span class=\"n\">CharField</span><span class=\"p\">()</span>\n        <span class=\"n\">prefix</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;foo&#39;</span>\n\n    <span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">Person</span><span class=\"p\">()</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">prefix</span><span class=\"p\">,</span> <span class=\"s1\">&#39;foo&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">Person</span><span class=\"p\">(</span><span class=\"n\">prefix</span><span class=\"o\">=</span><span class=\"s1\">&#39;bar&#39;</span><span class=\"p\">)</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">prefix</span><span class=\"p\">,</span> <span class=\"s1\">&#39;bar&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Esta nueva prueba comprueba que asignar un prefijo de nivel de clase funciona como se esperaba, y que pasar un parámetro <code class=\"docutils literal notranslate\"><span class=\"pre\">prefix</span></code> cuando se crea una instancia también funciona todavía.</p>\n<aside class=\"admonition-but-this-testing-thing-looks-kinda-hard admonition\">\n<p class=\"admonition-title\">Pero este asunto de las pruebas parece un poco difícil…</p>\n<p>Si usted nunca había tenido que lidiar con las pruebas anteriormente, pueden parecer un poco difíciles de escribir a primera vista. Afortunadamente, las pruebas son un tema muy importante en la programación, así que hay mucha información disponible:</p>\n<ul class=\"simple\">\n<li><p>Un buen primer vistazo a las pruebas de escritura para Django se puede encontrar en la documentación en: doc:/topics/testing/overview.</p></li>\n<li><p>Inmersión en Python (un libro en línea gratis para los desarrolladores principiantes de Python) incluye una gran <a href=\"#id14\"><span class=\"problematic\" id=\"id22\">`introducción a las pruebas unitarias`__</span></a>.</p></li>\n<li><p>After reading those, if you want something a little meatier to sink\nyour teeth into, there’s always the Python <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#module-unittest\" title=\"(en Python versión 3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">unittest</span></code></a> documentation.</p></li>\n</ul>\n</aside>\n</section>\n<section id=\"running-your-new-test\">\n<h3>Ejecutando su nueva prueba<a class=\"heading-anchor\" href=\"#running-your-new-test\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Recuerde que no hemos hecho todavía ninguna modificación al <code class=\"docutils literal notranslate\"><span class=\"pre\">BaseForm</span></code>, así que nuestras pruebas van a fallar. Vamos a ejecutar todas las pruebas en la carpeta <code class=\"docutils literal notranslate\"><span class=\"pre\">forms_tests</span></code> para asegurarnos de que es lo que realmente sucede. Desde la línea de comandos, cambiemos <code class=\"docutils literal notranslate\"><span class=\"pre\">cd</span></code> al directorio <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/</span></code> de Django y ejecutemos:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>./runtests.py<span class=\"w\"> </span>forms_tests\n</code></pre></div>\n<p>Si las pruebas se ejecutaron correctamente, usted debería ver tres fallos correspondientes a cada uno de los métodos de prueba que hemos añadido. Si todas las pruebas pasan, entonces usted querrá asegurarse de que ha agregado la nueva prueba mostrada arriba a la carpeta y clase apropiadas.</p>\n</section>\n</section>\n<section id=\"writing-the-code-for-your-ticket\">\n<h2>Escribiendo el código para su ticket<a class=\"heading-anchor\" href=\"#writing-the-code-for-your-ticket\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>A continuación vamos a estar agregando la funcionalidad descrita en el ticket <a class=\"extlink-ticket reference external\" href=\"https://code.djangoproject.com/ticket/24788\">#24788</a> a Django.</p>\n<section id=\"writing-the-code-for-ticket-24788\">\n<h3>Escribiendo el código para el ticket #24788<a class=\"heading-anchor\" href=\"#writing-the-code-for-ticket-24788\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Navegue a la carpeta <code class=\"docutils literal notranslate\"><span class=\"pre\">django/django/forms/</span></code> y abra el archivo <code class=\"docutils literal notranslate\"><span class=\"pre\">forms.py</span></code>. Encuentre la clase <code class=\"docutils literal notranslate\"><span class=\"pre\">BaseForm</span></code> en la línea 72 y agregue el atributo de clase <code class=\"docutils literal notranslate\"><span class=\"pre\">prefix</span></code> justo después del atributo <code class=\"docutils literal notranslate\"><span class=\"pre\">field_order</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BaseForm</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"c1\"># This is the main implementation of all the Form logic. Note that this</span>\n    <span class=\"c1\"># class is different than Form. See the comments by the Form class for</span>\n    <span class=\"c1\"># more information. Any improvements to the form API should be made to</span>\n    <span class=\"c1\"># *this* class, not to the Form class.</span>\n    <span class=\"n\">field_order</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n    <span class=\"n\">prefix</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n</code></pre></div>\n</section>\n<section id=\"verifying-your-test-now-passes\">\n<h3>Comprobando que ahora su prueba pase<a class=\"heading-anchor\" href=\"#verifying-your-test-now-passes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Una vez que haya terminado de modificar Django, tenemos que asegurarnos de que las pruebas que escribimos anteriormente pasan para que podamos ver si el código que escribimos arriba funciona correctamente. Para ejecutar las pruebas en la carpeta <code class=\"docutils literal notranslate\"><span class=\"pre\">forms_tests</span></code>, cambie al directorio <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/</span></code> de Django y ejecute:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>./runtests.py<span class=\"w\"> </span>forms_tests\n</code></pre></div>\n<p>¡Vaya, que bien que escribimos esas pruebas! Aún debe ver 3 fallos con la siguiente excepción</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"ne\">AssertionError</span><span class=\"p\">:</span> <span class=\"kc\">None</span> <span class=\"o\">!=</span> <span class=\"s1\">&#39;foo&#39;</span>\n</code></pre></div>\n<p>Olvidamos agregar la sentencia condicional en el método <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__</span></code>. Continúe y modifique <code class=\"docutils literal notranslate\"><span class=\"pre\">self.prefix</span> <span class=\"pre\">=</span> <span class=\"pre\">prefix</span></code> que ahora está en la línea 87 de <code class=\"docutils literal notranslate\"><span class=\"pre\">django/forms/forms.py</span></code>, añadiendo una sentencia condicional:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">if</span> <span class=\"n\">prefix</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">prefix</span> <span class=\"o\">=</span> <span class=\"n\">prefix</span>\n</code></pre></div>\n<p>Vuelva a ejecutar las pruebas y todas deben pasar. Si no es así, asegúrese de que ha modificado correctamente la clase <code class=\"docutils literal notranslate\"><span class=\"pre\">BaseForm</span></code> como se muestra arriba y que ha copiado las nuevas pruebas correctamente.</p>\n</section>\n</section>\n<section id=\"running-django-s-test-suite-for-the-second-time\">\n<h2>Ejecutando el conjunto de pruebas de Django por segunda vez<a class=\"heading-anchor\" href=\"#running-django-s-test-suite-for-the-second-time\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Una vez que haya verificado que su parche y su prueba funcionan correctamente, es una buena idea ejecutar todo el conjunto de pruebas de Django sólo para comprobar que su cambio no ha introducido ningún bug en otras áreas de Django. A pesar de que pasar con éxito todo el conjunto de pruebas no garantiza que su código está libre de errores, sí ayuda a identificar muchos bugs y regresiones que de otro modo podrían pasar desapercibidos.</p>\n<p>Para ejecutar todo el conjunto de pruebas de Django, cambie al directorio <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/</span></code> de Django y ejecute:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>./runtests.py\n</code></pre></div>\n<p>Siempre y cuando no haya fallos, ya está listo para arrancar.</p>\n</section>\n<section id=\"writing-documentation\">\n<h2>Escribiendo la documentación<a class=\"heading-anchor\" href=\"#writing-documentation\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Esta es una nueva característica, por lo tanto se debe documentar. Agregue la siguiente sección en la línea 1068 (al final del archivo) de django/docs/ref/forms/api.txt`:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>The prefix can also be specified on the form class::\n\n    &gt;&gt;&gt; class PersonForm(forms.Form):\n    ...     ...\n    ...     prefix = &#39;person&#39;\n\n.. versionadded:: 1.9\n\n    The ability to specify ``prefix`` on the form class was added.\n</code></pre></div>\n<p>Dado que esta nueva característica estará en una próxima versión también se añade a las notas de la versión de Django 1.9, en la línea 164 debajo de la sección «Formularios» en el archivo <code class=\"docutils literal notranslate\"><span class=\"pre\">docs/releases/1.9.txt</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>* A form prefix can be specified inside a form class, not only when\n  instantiating a form. See :ref:`form-prefix` for details.\n</code></pre></div>\n<p>Para obtener más información sobre escribir la documentación, incluyendo una explicación de lo que se trata el fragmento <code class=\"docutils literal notranslate\"><span class=\"pre\">versionadded</span></code>, consulte <a class=\"reference internal\" href=\"/es/1.11/internals/contributing/writing-documentation/\"><span class=\"doc\">Writing documentation</span></a>. Esa página incluye también una explicación de cómo generar una copia de la documentación localmente, por lo que puede obtener una vista previa del código HTML que se generará.</p>\n</section>\n<section id=\"previewing-your-changes\">\n<h2>Previewing your changes<a class=\"heading-anchor\" href=\"#previewing-your-changes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Now it’s time to go through all the changes made in our patch. To display the\ndifferences between your current copy of Django (with your changes) and the\nrevision that you initially checked out earlier in the tutorial:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>git<span class=\"w\"> </span>diff\n</code></pre></div>\n<p>Use the arrow keys to move up and down.</p>\n<div class=\"code-block\" data-language=\"diff\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Diff</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Diff code\"><code><span class=\"gh\">diff --git a/django/forms/forms.py b/django/forms/forms.py</span>\n<span class=\"gh\">index 509709f..d1370de 100644</span>\n<span class=\"gd\">--- a/django/forms/forms.py</span>\n<span class=\"gi\">+++ b/django/forms/forms.py</span>\n<span class=\"gu\">@@ -75,6 +75,7 @@ class BaseForm(object):</span>\n<span class=\"w\"> </span>    # information. Any improvements to the form API should be made to *this*\n<span class=\"w\"> </span>    # class, not to the Form class.\n<span class=\"w\"> </span>    field_order = None\n<span class=\"gi\">+    prefix = None</span>\n\n<span class=\"w\"> </span>    def __init__(self, data=None, files=None, auto_id=&#39;id_%s&#39;, prefix=None,\n<span class=\"w\"> </span>                 initial=None, error_class=ErrorList, label_suffix=None,\n<span class=\"gu\">@@ -83,7 +84,8 @@ class BaseForm(object):</span>\n<span class=\"w\"> </span>        self.data = data or {}\n<span class=\"w\"> </span>        self.files = files or {}\n<span class=\"w\"> </span>        self.auto_id = auto_id\n<span class=\"gd\">-        self.prefix = prefix</span>\n<span class=\"gi\">+        if prefix is not None:</span>\n<span class=\"gi\">+            self.prefix = prefix</span>\n<span class=\"w\"> </span>        self.initial = initial or {}\n<span class=\"w\"> </span>        self.error_class = error_class\n<span class=\"w\"> </span>        # Translators: This is the default suffix added to form field labels\n<span class=\"gh\">diff --git a/docs/ref/forms/api.txt b/docs/ref/forms/api.txt</span>\n<span class=\"gh\">index 3bc39cd..008170d 100644</span>\n<span class=\"gd\">--- a/docs/ref/forms/api.txt</span>\n<span class=\"gi\">+++ b/docs/ref/forms/api.txt</span>\n<span class=\"gu\">@@ -1065,3 +1065,13 @@ You can put several Django forms inside one ``&lt;form&gt;`` tag. To give each</span>\n<span class=\"w\"> </span>    &gt;&gt;&gt; print(father.as_ul())\n<span class=\"w\"> </span>    &lt;li&gt;&lt;label for=&quot;id_father-first_name&quot;&gt;First name:&lt;/label&gt; &lt;input type=&quot;text&quot; name=&quot;father-first_name&quot; id=&quot;id_father-first_name&quot; /&gt;&lt;/li&gt;\n<span class=\"w\"> </span>    &lt;li&gt;&lt;label for=&quot;id_father-last_name&quot;&gt;Last name:&lt;/label&gt; &lt;input type=&quot;text&quot; name=&quot;father-last_name&quot; id=&quot;id_father-last_name&quot; /&gt;&lt;/li&gt;\n<span class=\"gi\">+</span>\n<span class=\"gi\">+The prefix can also be specified on the form class::</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+    &gt;&gt;&gt; class PersonForm(forms.Form):</span>\n<span class=\"gi\">+    ...     ...</span>\n<span class=\"gi\">+    ...     prefix = &#39;person&#39;</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+.. versionadded:: 1.9</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+    The ability to specify ``prefix`` on the form class was added.</span>\n<span class=\"gh\">diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt</span>\n<span class=\"gh\">index 5b58f79..f9bb9de 100644</span>\n<span class=\"gd\">--- a/docs/releases/1.9.txt</span>\n<span class=\"gi\">+++ b/docs/releases/1.9.txt</span>\n<span class=\"gu\">@@ -161,6 +161,9 @@ Forms</span>\n<span class=\"w\"> </span>  :attr:`~django.forms.Form.field_order` attribute, the ``field_order``\n<span class=\"w\"> </span>  constructor argument , or the :meth:`~django.forms.Form.order_fields` method.\n\n<span class=\"gi\">+* A form prefix can be specified inside a form class, not only when</span>\n<span class=\"gi\">+  instantiating a form. See :ref:`form-prefix` for details.</span>\n<span class=\"gi\">+</span>\n<span class=\"w\"> </span>Generic Views\n<span class=\"w\"> </span>^^^^^^^^^^^^^\n\n<span class=\"gh\">diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py</span>\n<span class=\"gh\">index 690f205..e07fae2 100644</span>\n<span class=\"gd\">--- a/tests/forms_tests/tests/test_forms.py</span>\n<span class=\"gi\">+++ b/tests/forms_tests/tests/test_forms.py</span>\n<span class=\"gu\">@@ -1671,6 +1671,18 @@ class FormsTestCase(SimpleTestCase):</span>\n<span class=\"w\"> </span>        self.assertEqual(p.cleaned_data[&#39;last_name&#39;], &#39;Lennon&#39;)\n<span class=\"w\"> </span>        self.assertEqual(p.cleaned_data[&#39;birthday&#39;], datetime.date(1940, 10, 9))\n\n<span class=\"gi\">+    def test_class_prefix(self):</span>\n<span class=\"gi\">+        # Prefix can be also specified at the class level.</span>\n<span class=\"gi\">+        class Person(Form):</span>\n<span class=\"gi\">+            first_name = CharField()</span>\n<span class=\"gi\">+            prefix = &#39;foo&#39;</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+        p = Person()</span>\n<span class=\"gi\">+        self.assertEqual(p.prefix, &#39;foo&#39;)</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+        p = Person(prefix=&#39;bar&#39;)</span>\n<span class=\"gi\">+        self.assertEqual(p.prefix, &#39;bar&#39;)</span>\n<span class=\"gi\">+</span>\n<span class=\"w\"> </span>    def test_forms_with_null_boolean(self):\n<span class=\"w\"> </span>        # NullBooleanField is a bit of a special case because its presentation (widget)\n<span class=\"w\"> </span>        # is different than its data. This is handled transparently, though.\n</code></pre></div>\n<p>When you’re done previewing the patch, hit the <code class=\"docutils literal notranslate\"><span class=\"pre\">q</span></code> key to return to the\ncommand line. If the patch’s content looked okay, it’s time to commit the\nchanges.</p>\n</section>\n<section id=\"committing-the-changes-in-the-patch\">\n<h2>Committing the changes in the patch<a class=\"heading-anchor\" href=\"#committing-the-changes-in-the-patch\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>To commit the changes:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>git<span class=\"w\"> </span>commit<span class=\"w\"> </span>-a\n</code></pre></div>\n<p>This opens up a text editor to type the commit message. Follow the <a class=\"reference internal\" href=\"/es/1.11/internals/contributing/committing-code/#committing-guidelines\"><span class=\"std std-ref\">commit\nmessage guidelines</span></a> and write a message like:</p>\n<div class=\"code-block\" data-language=\"text\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Text</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Text code\"><code>Fixed #24788 -- Allowed Forms to specify a prefix at the class level.\n</code></pre></div>\n</section>\n<section id=\"pushing-the-commit-and-making-a-pull-request\">\n<h2>Pushing the commit and making a pull request<a class=\"heading-anchor\" href=\"#pushing-the-commit-and-making-a-pull-request\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>After committing the patch, send it to your fork on GitHub (substitute\n«ticket_24788» with the name of your branch if it’s different):</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>git<span class=\"w\"> </span>push<span class=\"w\"> </span>origin<span class=\"w\"> </span>ticket_24788\n</code></pre></div>\n<p>You can create a pull request by visiting the <a class=\"reference external\" href=\"https://github.com/django/django/\">Django GitHub page</a>. You’ll see your branch under «Your\nrecently pushed branches». Click «Compare &amp; pull request» next to it.</p>\n<p>Please don’t do it for this tutorial, but on the next page that displays a\npreview of the patch, you would click «Create pull request».</p>\n</section>\n<section id=\"next-steps\">\n<h2>Next steps<a class=\"heading-anchor\" href=\"#next-steps\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Congratulations, you’ve learned how to make a pull request to Django! Details\nof more advanced techniques you may need are in\n<a class=\"reference internal\" href=\"/es/1.11/internals/contributing/writing-code/working-with-git/\"><span class=\"doc\">Working with Git and GitHub</span></a>.</p>\n<p>Now you can put those skills to good use by helping to improve Django’s\ncodebase.</p>\n<section id=\"more-information-for-new-contributors\">\n<h3>Más información para los nuevos colaboradores<a class=\"heading-anchor\" href=\"#more-information-for-new-contributors\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Antes de que se involucre mucho en la escritura de parches para Django, hay algo más de información sobre cómo contribuir a la que probablemente debería echarle un vistazo:</p>\n<ul class=\"simple\">\n<li><p>Debe asegurarse de leer la documentación de Django sobre <a class=\"reference internal\" href=\"/es/1.11/internals/contributing/writing-code/submitting-patches/\"><span class=\"doc\">reclamar tickets y enviar parches</span></a>. Esta incluye la etiqueta de Trac, cómo reclamar tickets para uno mismo, el estilo esperado de codificación para parches y muchos otros detalles importantes.</p></li>\n<li><p>Las personas que colaboran por primera vez también deben leer <a class=\"reference internal\" href=\"/es/1.11/internals/contributing/new-contributors/\"><span class=\"doc\">la documentación para los colaboradores principiantes</span></a> de Django. Tiene muchos buenos consejos para aquellos de nosotros que somos nuevos en esto de colaborar con Django.</p></li>\n<li><p>Después de ellos, si todavía quiere más información sobre cómo contribuir, siempre se puede navegar por el resto de <a class=\"reference internal\" href=\"/es/1.11/internals/contributing/\"><span class=\"doc\">la documentación de Django sobre cómo contribuir</span></a>. Este contiene un montón de información útil y debe ser su primera fuente para responder a cualquier pregunta que pueda tener.</p></li>\n</ul>\n</section>\n<section id=\"finding-your-first-real-ticket\">\n<h3>Encontrando su primer ticket real<a class=\"heading-anchor\" href=\"#finding-your-first-real-ticket\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Una vez que haya revisado parte de esa información, estará listo para salir y encontrar un ticket al cual escribirle un parche. Preste especial atención a los tickets con el criterio de «easy pickings». Estos tickets son a menudo de carácter mucho más simples y son geniales para los que colaboran por primera vez. Una vez que esté familiarizado con como contribuir con Django, puede pasar a escribir parches para los tickets más difíciles y complicados.</p>\n<p>Si lo que desea es empezar ya (¡Y nadie lo culparía!), trate de echar un vistazo a la lista de <a href=\"#id14\"><span class=\"problematic\" id=\"id23\">`los tickets sencillos que necesitan parches`__</span></a> y <a href=\"#id14\"><span class=\"problematic\" id=\"id24\">`los tickets sencillos que tienen parches que necesitan mejoras`__</span></a>. Si se siente cómodo con la escritura de pruebas también puede ver la lista de “tickets sencillos que necesitan pruebas`__. Sólo recuerde seguir las directrices sobre cómo reclamar tickets que se mencionaron en el enlace a la documentación de Django sobre <a class=\"reference internal\" href=\"/es/1.11/internals/contributing/writing-code/submitting-patches/\"><span class=\"doc\">reclamar tickets y enviar parches</span></a>.</p>\n</section>\n<section id=\"what-s-next-after-creating-a-pull-request\">\n<h3>What’s next after creating a pull request?<a class=\"heading-anchor\" href=\"#what-s-next-after-creating-a-pull-request\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>After a ticket has a patch, it needs to be reviewed by a second set of eyes.\nAfter submitting a pull request, update the ticket metadata by setting the\nflags on the ticket to say «has patch», «doesn’t need tests», etc, so others\ncan find it for review. Contributing doesn’t necessarily always mean writing a\npatch from scratch. Reviewing existing patches is also a very helpful\ncontribution. See <a class=\"reference internal\" href=\"/es/1.11/internals/contributing/triaging-tickets/\"><span class=\"doc\">Clasificando tickets</span></a> for details.</p>\n</section>\n</section>","rootId":"writing-your-first-patch-for-django","toc":[{"title":"Introducción","anchor":"introduction","children":[{"title":"¿Para quién es este tutorial?","anchor":"who-s-this-tutorial-for","children":[]},{"title":"¿Qué cubre esta guía?","anchor":"what-does-this-tutorial-cover","children":[]}]},{"title":"Código de Conducta","anchor":"code-of-conduct","children":[]},{"title":"Instalando Git","anchor":"installing-git","children":[]},{"title":"Obtener una copia de la versión de desarrollo de Django","anchor":"getting-a-copy-of-django-s-development-version","children":[]},{"title":"Restaurar una versión previa de Django","anchor":"rolling-back-to-a-previous-revision-of-django","children":[]},{"title":"Ejecutando el conjunto de pruebas de Django por primera vez","anchor":"running-django-s-test-suite-for-the-first-time","children":[]},{"title":"Creating a branch for your patch","anchor":"creating-a-branch-for-your-patch","children":[]},{"title":"Escribiendo algunas pruebas para su reporte","anchor":"writing-some-tests-for-your-ticket","children":[{"title":"Escribiendo algunas pruebas para el ticket #24788","anchor":"writing-some-tests-for-ticket-24788","children":[]},{"title":"Ejecutando su nueva prueba","anchor":"running-your-new-test","children":[]}]},{"title":"Escribiendo el código para su ticket","anchor":"writing-the-code-for-your-ticket","children":[{"title":"Escribiendo el código para el ticket #24788","anchor":"writing-the-code-for-ticket-24788","children":[]},{"title":"Comprobando que ahora su prueba pase","anchor":"verifying-your-test-now-passes","children":[]}]},{"title":"Ejecutando el conjunto de pruebas de Django por segunda vez","anchor":"running-django-s-test-suite-for-the-second-time","children":[]},{"title":"Escribiendo la documentación","anchor":"writing-documentation","children":[]},{"title":"Previewing your changes","anchor":"previewing-your-changes","children":[]},{"title":"Committing the changes in the patch","anchor":"committing-the-changes-in-the-patch","children":[]},{"title":"Pushing the commit and making a pull request","anchor":"pushing-the-commit-and-making-a-pull-request","children":[]},{"title":"Next steps","anchor":"next-steps","children":[{"title":"Más información para los nuevos colaboradores","anchor":"more-information-for-new-contributors","children":[]},{"title":"Encontrando su primer ticket real","anchor":"finding-your-first-real-ticket","children":[]},{"title":"What’s next after creating a pull request?","anchor":"what-s-next-after-creating-a-pull-request","children":[]}]}],"breadcrumbs":[{"docname":"intro/index","title":"Empezando","url":"/es/1.11/intro/"}],"prev":{"docname":"intro/whatsnext","title":"Qué leer después","url":"/es/1.11/intro/whatsnext/"},"next":{"docname":"topics/index","title":"Using Django","url":"/es/1.11/topics/"},"formats":{"html":"/es/1.11/intro/contributing/","markdown":"/es/1.11/intro/contributing.md","json":"/es/1.11/intro/contributing.json"},"source":"https://github.com/django/django/blob/stable/1.11.x/docs/intro/contributing.txt","official":"https://docs.djangoproject.com/es/1.11/intro/contributing/","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","fr","ja","id","pt-br","ko","es","el","pl"]}