Comunidad de diseño web y desarrollo en internet

Python en la web con Django (III): mapear URLs y Vistas

Aquí vamos a explicar cómo Django busca y maneja URLs siguiendo una tabla de contenidos donde se relacionan URLs a vistas.

Construyendo nuestra primera vista


Lo primero que debemos saber es qué queremos decir cuando hablamos de vistas. Vista o función de vista es una función de Python que toma como argumento una petición web (request) y devuelve una respuesta (response). Ahora mejor ¿verdad?

Vamos a crear una muy sencilla a modo de ejemplo y la explicamos. Copiad el código de debajo y crearlo en un fichero que llamaremos firstView.py dentro de nuestra carpeta tutorial (si no sabéis que significa estas carpetas por favor revisad el anterior tutorial Python en la web con Django (II): creando nuestro proyecto.

Código :

alberto@a-AMILO-Si-3655:~/django/tutorial$ view firstView.py 
1 from django.http import HttpResponse
2 
3 def holaMundo(request):
4         html = "<html><body>Hola Mundo desde DJANGO</body></html>"
5         return HttpResponse(html)

Como dijo Jack el Destripador vamos por partes:

  • Línea 1: Importamos la clase HttpResponse que pertenece al modulo django.http. Este objeto lo necesitaremos para dar la respuesta a la petición web.
  • Línea 3: definimos la función holaMundo. Este es el nombre de nuestra vista y como podéis ver es una simple función.
  • Línea 4: creamos una variable html que contiene el contenido de la respuesta a dar al servidor. Como sabéis en Python no es necesario declarar la variable indicando el tipo de datos que contiene.
  • Línea 5: la vista devuelve un objeto HttpResponse al que pasamos como parámetro la variable con el HTML.

Fácil ¿verdad? Ya lo iremos complicando tranquilos.

Asociando una URL a nuestra vista


Como dijimos en el anterior tutorial "Creando nuestro proyecto", el fichero urls.py contiene la declaración de las URLs posibles para nuestro proyecto y su vista asociada. ¿A que ahora suena mejor? Si abrimos el fichero urls.py sin modificarlo esto es lo que vemos:

Código :

alberto@a-AMILO-Si-3655:~/django/tutorial$ view urls.py
1 from django.conf.urls.defaults import patterns, include, url
2 
3 # Uncomment the next two lines to enable the admin:
4 # from django.contrib import admin
5 # admin.autodiscover()
6
7 urlpatterns = patterns('',
8     # Examples:
9     # url(r'^$', 'tutorial.views.home', name='home'),
10    # url(r'^tutorial/', include('tutorial.foo.urls')),
11
12    # Uncomment the admin/doc line below to enable admin documentation:
13    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
14
15    # Uncomment the next line to enable the admin:
16    # url(r'^admin/', include(admin.site.urls)),
17 )

Vemos como este fichero contiene dos puntos importantes:

  • Línea 1: Importación de paquetes necesarios para que django realice la redirección de URLs a vistas.
  • Línea 7: Variable urlpatterns. Esta variable recibe el resultado de llamar a la función patterns a la que pasamos como parámetro una tupla con elementos URLpattern. Estos elementos siguen el patrón (url, función).

Si quitásemos las líneas comentadas vemos que sólo nos quedaría dentro de la función patterns lo siguiente: '', . Algún día os contaré qué es eso...de momento que sepáis que debe estar ahí.
Bien vamos a agregar nuestra vista. Para ello vamos a modificar el fichero urls.py y dejarlo de la siguiente manera (si no queréis no quitéis los comentarios, yo lo hago para que se vea más claro pero cuantos más comentarios mejor):

Código :

alberto@a-AMILO-Si-3655:~/django/tutorial$ view urls.py
1 from django.conf.urls.defaults import patterns, include, url
2 from tutorial.firstView import holaMundo, suma
3 
4 urlpatterns = patterns('',
5         (r'^hola$',holaMundo),
6 )


  • Línea 1: Importación de paquetes necesarios para que django realice la redirección de URLs a vistas.
  • Línea 2: Importamos de nuestro modulo firstView la vista holaMundo
  • Línea 5: Añadimos nuestra expresión regular de URL y nuestra vista.


Llegados a este punto cosas que os podéis preguntar:

¿Esto funciona?


Por supuesto o eso espero. Ves al navegador y escribe la dirección http://127.0.0.1:8000/hola
Recuerda que debes tener el servidor corriendo (comando: python manage.py runserver)

¿Qué significa esto r'^hola/$'?


Esto es una expresión regular que aunque es un tema interesantísimo no voy a extenderme:

  • El caracter r antes de la cadena de texto indica que es una cadena de caracteres en crudo. Esto permite que no tengamos que poner constantemente sentencias de escape para caracteres propios de expresiones regulares.
  • El caracter ^ indica el comienzo de nuestra expresión. Significa que obligatoriamente la URL deberá empezar con la letra h seguido de 'ola/'.
  • El caracter $ indica el fin de nuestra expresión. Significa que la palabra debe terminar con /.

¿Qué pasaría si no indicásemos el caracter ^?


Pues que nuestra URL podría ser http://127.0.0.1:8000/aaaaaaaahola o http://127.0.0.1:8000/cristalab/acha4m0/hola/

¿Qué pasaría si no indicásemos el caracter $?


Pues que nuestra URL podría ser http://127.0.0.1:8000/hola/cristalab/ach4m0 o http://127.0.0.1:8000/hola/a/a/A/a/
Ya veis que es un tema divertido pero a la vez muy peligroso. Yo recomiendo siempre que las URLs tengan indicador de inicio y de fin.

¿Y si no pongo la barra del final?


Pues que la dirección dará error. Por defecto, al invocar una URL django añade el caracter / al final y no es lo mismo hola/ que hola ¿verdad?

¿Se pueden pasar funciones como parámetros?


¡Para de hacer preguntas! Si se puede. Las funciones en Python son objetos de primera clase, lo que significa que puedes pasarlo como cualquier otra variable.

Pasando parámetros a las vistas


Bien, ya hemos hecho nuestra primera vista Hola Mundo (un clásico vamos). Ahora vamos a ir un poco más allá.
Os propongo el siguiente problema. ¡Quiero que invocando a una URL pueda sumar dos números! Esos dos números irán en la URL de la siguiente manera: numero_1/numero_2

Consejo: si queréis añadir algo nuevo a un proyecto primero crear la función de vista y después el mapeo de URL. Es que yo odio los errores 404...soy así.

Modificamos nuestro paquete firstView para que quede de la siguiente manera:

Código :

alberto@a-AMILO-Si-3655:~/django/tutorial$ cat firstView.py
1 from django.http import HttpResponse
2 
3 def holaMundo(request):
4          html = "<html><body>Hola Mundo desde DJANGO</body></html>"
5          return HttpResponse(html)
6 
7 def suma(request,num1,num2):
8          op1 = int(num1)
9          op2 = int(num2)
10         html = "<html><body>La suma de los numeros es: %s </body></html>" % (op1+op2)
11         return HttpResponse(html)

Repasemos la funcion de vista suma:

  • Línea 7: Toma además de la petición (request) dos parámetros más(num1 y num2)
  • Línea 8 y 9: Convierte las variables num1 y num2 a enteros. Esto es importante, todos los parámetros que recojamos de nuestra URL son cadenas de texto por lo que tenemos que convertirlos a números si no queréis ver un error en el navegador.
  • Línea 10: Preparando nuestro html básico. %s significa que ese caracter debe sustituirse por lo que venga después de la cadena y del símbolo % entre paréntesis. En nuestro caso %s pasara a ser la suma de las variables op1 y op2. Este método ya lo usaba C en su maravilloso printf.

Bueno tiene buena pinta, vamos ahora a redirigir la URL a nuestra función:

Código :

alberto@a-AMILO-Si-3655:~/django/tutorial$ view urls.py
1 from django.conf.urls.defaults import patterns, include, url
2 from tutorial.firstView import holaMundo, suma
3 
4 urlpatterns = patterns('',
5         (r'^hola$',holaMundo),
6         (r'^suma/(\d+)/(\d+)/$',suma),
7 )


  • Línea 2: atentos que ahora tenemos que importar nuestra función de vista suma
  • Línea 7: indicamos que nuestra URL tiene que empezar con la palabra suma seguido del carácter / después un digito o dígitos cualquiera después otra barra después otro digito o dígitos cualquiera y acabar con otra barra. Uff algo más dura esta ya ¿eh?

Los caracteres \d+ indican que podemos incluir cualquier digito ya sea 1 o 50 o 200000. Si quitásemos el símbolo + únicamente podríamos incluir 1 digito que va del 0 al 9. Fuera de eso daría error.
¿Por qué lo incluimos entre paréntesis? Aquí está la magia. Al incluirlo entre paréntesis estamos indicando a django que queremos pasar lo que este dentro a la función de vista. El orden de lectura es de izquierda a derecha por lo que el primer número que recogemos será el que esté más pegado a suma y el segundo el que esté al final de la dirección.

Ya podemos jugar con las URLs: http://127.0.0.1:8000/suma/30/50/ o http://127.0.0.1:8000/suma/30/5000000/

Bueno ¿qué os va pareciendo? La verdad que este tutorial tiene algo más de chicha porque los otros eran un tanto aburridos aunque muy necesarios.

Esta manera de hacer las cosas no se usa. Tú no vas a escribirte una página web impresionante, por ejemplo cristalab, en una variable que se llame HTML. Lo que usaras serán plantillas y dejaras a los diseñadores con las plantillas y a los programadores con el código python.

Pues en el próximo capitulo veremos las plantillas y la herencia de plantillas.

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate