Curso Django: Las vistas
Esta semana nos toca ver el tema de vistas, no se olviden que si este es el primer artículo que leen sobre Django en Maestros del Web, deben revisar la guía por completo, incluyendo los comentarios, donde se solucionaron muchas dudas, es necesario para que comprendan los ejemplos y aprendan fácilmente Django.
Vistas
Un función de vista o una vista, como es conocida generalmente, es una función en Python que hace una solicitud Web y devuelve una respuesta Web, esta respuesta puede ser el contenido de una página, un error 404, una imagen, un documento XML, entre muchas cosas más.
La vista contiene toda la lógica necesaria para devolver una respuesta, todas estas respuestas se encuentran en un único archivo y este archivo se llama: views.py, que se encuentra dentro de cada aplicación de Django.
Las consultas y las vistas
En el capítulo anterior, jugamos con algunas consultas, estas consultas son parte fundamental de las vistas, permiten elegir que tipo de contenido se visualizará. Revisa y practica, si no lo hiciste, para poder obtener mejores resultados.
Las plantillas y las vistas
Las plantillas son muy importantes, permiten acomodar el resultado que devuelve la vista. Django tiene un estupendo motor de plantillas que permite separar eficientemente la presentación, de la lógica de programación, esta semana trabajaremos con algunas plantillas simples para no causar confusión.
Proyecto de ejemplo: las vistas
Para esta semana debemos tener en cuenta que nuestros modelos almacenados en models.py dentro de la aplicación principal, quedaron así:
Rellenamos algunos datos para poder tener resultados:
Con estos datos empezaremos a hacer algunas vistas para nuestro proyecto. Empezaremos con las importaciones necesarias, que son estas:
La primera de ellas es porque necesitamos los modelos, la segunda línea para poder usar los datos del modelo usuario, la tercera línea es la respuesta más simple (HttpResponse), la cuarta importa: render_to_response (para las plantillas) y get_object_or_404 (para lanzar un error 404, de no encontrar ningún valor almacenado) y la quinta línea importa el RequestContext (en este caso para poder usar la ruta de las imágenes almacenadas previamente en la carpeta carga y referenciadas por la url media).
Ahora pasemos a ver donde usamos específicamente cada uno de estos componentes.
Vista: sobre
Esta vista es un ejemplo muy simple del uso de HttpResponse, está devolviendo el contenido HTML:
Nota:
Debemos tener en cuenta que siempre debemos acompañar una vista de su configuración en urls.py, así que en este archivo debemos tener esta línea: (ubicada dentro de patterns)
url(r'^sobre/$','principal.views.sobre'),
Lanzamos nuestro servidor de desarrollo:(como todas las semanas)
python manage.py runserver
Y vamos a la dirección:
http://127.0.0.1:8000/sobre/
Vista: Inicio
La vista inicio, hace una consulta de todas las recetas y las almacena en una variable llamada recetas (también), es aquí donde es apropiado usar render_to_response para poder indicarle que vamos a usar la plantilla inicio.html, y que le pasaremos en un diccionario (concepto de python), el resultado de la consulta.
La plantilla inicio.html debemos crearla en la carpeta ‘plantillas’ que se encuentra en ‘recetario’ (creada previamente en capítulos anteriores), su contenido debe ser similar al siguiente:
Veremos unos símbolos {% %} que por no deben distraernos, así que no entraré en detalles al respecto, pueden intuir de que trata, pero prefiero no confundirlos y dejarlos para la próxima semana.
Ahora igual que el ejemplo anterior debemos agregar la siguiente línea en nuestra configuración de las url en urls.py:
url(r'^$','principal.views.inicio'),
Nuestro servidor debe estar funcionando y podemos ingresar a la siguiente dirección:
Vista: usuarios
Esta vista saca los datos de los usuarios registrados, y las recetas registradas. Y repite el mismo procedimiento de la vista anterior.
La plantilla usuarios.html debe ser creada en la carpeta plantillas y debe tener un contenido similar al siguiente:
En esta plantilla se estan juntando a los usuarios y sus respectivas recetas, agregamos la siguiente regla al urls.py:
url(r'^usuarios/$','principal.views.usuarios'),
para ver el resultado (servidor corriendo), debemos entrar a:
http://127.0.0.1:8000/usuarios/
Vista: lista_recetas
Esta vista, se diferencia de las anteriores por el uso de context_instance=RequestContext(request), usada para indicarle a la plantilla el parámetro {{MEDIA_URL}} que referencia a la ruta de las imágenes, la plantilla recetas.html, debe quedar así:
La línea en urls.py debe ser así:
url(r'^recetas/$','principal.views.lista_recetas'),
Y se deben visualizar los resultados en:
http://127.0.0.1:8000/recetas/
Vista: detalle_receta
Esta vista recibe un parametro mas: id_receta, que le sirve para hacer una consulta del detalle de esa receta (corresponde a su llave primaria) y usa get_object_or_404(Receta, pk=id_receta), para obtener un objeto o un error 404 en caso de no encontrar resultado alguno.
Con este resultado, se realiza una consulta para obtener sus comentarios. La plantilla receta.html, quedará así:
La línea en urls.py debe ser así: (notar las expresiones regulares en python)
url(r'^receta/(?P<id_receta>\d+)$','principal.views.detalle_receta'),
Y se deben visualizar los resultados al darle clic en los enlaces a recetas en:
http://127.0.0.1:8000/recetas/
Archivo final: views.py
Al final de todo, views.py debe quedar de esta manera:
Archivo: urls.py
El archivo urls.py, permite tener unas urls limpias, para nuestro ejemplo este debe quedar de la siguiente manera: (si fuiste impaciente, regresa a la vista: sobre )
Para finalizar, si se perdieron con alguna línea o si desean corroborar que todo va bien, pueden estar pendientes del repositorio del proyecto.
La próxima semana veremos el tema de las plantillas con un poco más de detalle, practiquen haciendo sus propias vistas, usando las consultas que aprendieron en el capítulo anterior y complementen lo aprendido con un vistazo a la documentación oficial, que nunca esta demás. Que tengan buen inicio de semana :).
Genial gracias por tomarte el tiempo de hacer estos tutoriales, no esta demas mirar como vas desarrollando los temas de manera adecuada y secuencial eso ayuda mucho a pesar de que ya haya leido y probado todo esto. Me parece super y aprendo mas, quiero estar mas inmerso en esto de Python y Django , y pues Django es mi favorito en Framework Web’s :3
Muchas gracias Danilo, por seguir el curso, trataré de mantenerlo simple y secuencial, a pesar de que mientras se va avanzando más en el curso, se hace más dificil mantener la simplicidad de las explicaciones.
Muy buen manual sobre el uso del Django. A parte de ayudarme a aprender un poco mas sobre Django, que me parece un framework muy potente para el desarollo de aplicaciones web, me esta ayudando a resolver y mejorar el proyecto final de carrera para tenerlo a punto para la presentación xDDD
Haber si llegamos a la lección para la puesta en producción porque no le he conseguido xDDD
Hola Xavier, gracias por seguir el curso. El último capítulo está orientado al despliegue en el servidor y la publicación del proyecto.
Un saludo
Una aclaración con respecto a la vista: lista_receta, para usar context_instance=RequestContext(request), no deben olvidar importarlo usando: from django.template import RequestContext (en las líneas de importación), esto se puede observar en la imágen completa del views.py
Muy buen manual, lo sigo desde que inicio, y Django me parece un framework genial; simplifica muchísimo el trabajo, felicidades.
En este capitulo no me funcionó lo del MEDIA_URL, aunque lo solucione colocando ‘/media/{{item.imagen}}’ como ruta de imagen, no se si a alguien mas tenga problemas con esto.
Saludos!
excelente el curso sergio,
gracias por compartir toda esta informacion de Django. es estupendo este framework, cada semana que pasa se poner mejor y con muchisimas ganas de comencemos con las plantillas…
excelente el tutorial. todo me resulta bien
el problema que tengo es que no me muestra la imagen. solo un tamaño que lo puso en el style. pero
no aparece nada. no se a que se deba.
mil gracias por todo.
Gracias por tomarte el tiempo de veras , ojala puedes hacer un pdf con cada clasecita asi me lo guardo, cuando termine el curso y puede enseñar a mis compañeros :3
Cuando dan un curso de instalacion de python y django en un hosting 😉 gracias x el curso está demasiado bueno @maestros , @neosergio 😀
muy buen aporte, pero tengo una inquietud, donde incluyo los archivos de estilo (css) para mejorar la presentación de la pagina.
Muy buen curso
Para que funcione el parámetro {{MEDIA_URL}} hay que poner el valor que se quiera que tenga en el fichero settings.py; yo he puesto esto MEDIA_URL = ‘/media/’ y me está funcionando
Muchas gracias por el curso
Hola Danilo, al final el curso estará disponible en formatos: .PDF, .epub y disponible en Amazon para el Kindle.
Podrías dar mayores detalles del error quizas, puedes contactarme por Twitter (@neosergio) para ayudarte
En el último capítulo del curso, veremos que opciones tenemos para publicar nuestro proyecto, incluyendo hosting
CSS es un tipo de archivo estático, por ello lo veremos en el capítulo 8: los archivos estáticos, dentro de 3 semanas
Hola, Sergio. Gracias por el gran material que estas publicando.
Estoy acostumbrado al modelo MVC con php, separando los modelos, controladores y vistas en lados diferentes. Es mas cada función(como recetas, comentarios) tiene un archivo propio y entonces el código es mas legible. Con django veo que todo el código se almacena en models.py y views.py, si tengo una gran cantidad de vistas y modelos que poner dentro de la app, ¿acaso esto quitaría la legibilidad del código? o lo haria menos eficiente?. PDT No intento ser purista solo que veo que puede marear tener todo en un solo archivo.
Que tal Jorge.
Yo también me preguntaba lo mismo y realizando los ejercicios de este capitulo, al menos en lo que respecta a las vistas parece que estas si pueden estar distribuidas en diferentes carpetas físicas, y en el archivo urls.py le indicas esa carpeta, según yo, no lo he probado aún.
De cualquier manera esperamos a que el buen Sergio nos conteste.
Saludos.
Que tal sergio, te hago una consulta. Yo a través de la barra de direcciones hago una consulta Http, esta consulta llega al archivo “urls.py” y este busca la funcion asociada en “views.py”. Ahora mi pregunta es: como hago para hacer una consulta Http pero no desde la barra de direcciones, sino desde un metodo de python? Por ejemplo algo como esto: >>> HttpRequest(‘/prueba/’). Quiero hacer una redireccion automatica.
Hola Jorge y Daniel. Es una de las ventajas de python, tu puedes dividir tus modelos en diversos archivos, como muchos lo hacen, el uso de models responde a que es mas simple acceder al nombre de la aplicacion.models y saber que ahi se encuentran todos los modelos, ten en cuenta también que si tienes mas colaboradores dentro de tu proyecto, debes documentar con precisión para que evites que tu distribución de modelos se torne confusa. Muchos incluso crean una carpeta models y dentro de estos archivos con modelos, eso también puede servir. En StackOverflow hubo una pregunta muy similar y las respuestas te darán mayores referencias (http://stackoverflow.com/questions/1884990/refactor-large-models-py-file-in-django-app).
Un saludo y gracias por seguir el curso
Puedes usar un HttpResponseRedirect (https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpResponseRedirect)
Algo asi:
return HttpResponseRedirect(‘/ruta’)
Me ayuda mucho tus tutoriales para aprender Django
bueno aca mi codigo jejeje 😀
https://github.com/marti1125/Receta_Django
DEFINITIVAMENTE MUCHAS GRACIAS SERGIO, ERES LO MAXIMO, GRACIAS POR DARTE EL TIEMPO DE REALIZAR ESTE CURSO LA VERDAD QUE ME ESTA AYUDANDO BASTANTE, OJALA QUE TE ANIMES A REALIZAR UN VIDEOTUTORIAL ASI ESTARIA MUCHO MAS ENTENDIBLE, PERO LO QUE HACES BASTA, GRACIAS GRACIAS
Nada mas que decir…Gracias..estoy aprendiendo mucho…pero tengio una duda.
class Comentario(models.Model):
receta = models.ForeignKey(Receta)
texto = models.TextField(help_text=’Tu comentario’, verbose_name=’Comentario’)
def __unicode__(self):
return self.texto
!!!!Para que sirve este texto???
def __unicode__(self):
return self.texto
En los modelos…
Muchas Gracias
“def __unicode__(self)” se ejecuta cuando haces un print de un objeto de esa clase. En este caso si haces un print de un objeto comentario obtenido desde la base de datos imprimiría la variable texto. Podes concatenar campos si queres una impresion mas informativa.
Lo del videotutorial es una buena idea, otra versión del curso, para los que aprendan mejor con videos. Al final del curso, prepararé uno.
Hola Julio, con respecto al {{ MEDIA_URL }} no te sale nada cuando lo pones en la plantilla ya que en tu archivo settings.py lo tienes vacio, busca la variable MEDIA_URL en settings.py y dejalo asi MEDIA_URL = ‘/media/’ …. cuando lo hagas en tu plantilla pon: ‘{{ MEDIA_URL }}{{item.imagen}}’ …. y todo deberia funcionar
todo bien solo tenia problemas con las imágenes pero gracias a Sergio : http://www.maestrosdelweb.com/editorial/curso-django-las-vistas/#comment-196720
se soluciono el problema de que no las mostraba.
Hola que tal, antes que nada te felicito por este curso he aprendido bastante, quiero preguntarte por la cuestión de los comentarios yo lo hago de una forma un poco distinta, yo hago lo siguiente:
Primero obtengo la receta => receta = Receta.objects.get(pk=id_receta)
y para obtener los comentarios de esa receta :
comentarios = receta.comentario_set.all()
podrías decirme si es una buena práctica hacerlo así o si existen diferencias con el método que utilizas. Gracias
hola muy bueno el tuto los estoy siguiendo y todo bien solo tengo problemas con las imagenes en el settingns tengo: MEDIA_URL = ‘/media/’ y en recetas.html: li>
{{dato.titulo}}
si me pueden ayudar
Hay muchas maneras de hacer consultas, la diferencia podría estar en la velocidad y la cantidad de recursos que usan, asi que quizas podrías instalar “django debug toolbar” (https://github.com/django-debug-toolbar/django-debug-toolbar) y hacer tus evaluaciones
No salió el código que querías que viera, puedes usar http://gist.github.com o http://pastie.org para poder ver de que trata?? y poder ayudarte. No te olvides mirar el repositorio del proyecto para resolver dudas, también
Hola Sergio,
Describes una fotografia con “La primera de ellas es porque necesitamos los modelos, la segunda línea para poder usar los datos del modelo usuario, la tercera línea es la respuesta más simple (HttpResponse), la cuarta importa: render_to_response (para las plantillas) y get_object_or_404 (para lanzar un error 404, de no encontrar ningún valor almacenado) y la quinta línea importa el RequestContext (en este caso para poder usar la ruta de las imágenes almacenadas previamente en la carpeta carga y referenciadas por la url media).”
Pero en la captura solo aparecen 3 lineas , supongo que es una tonteria pero para que puedas modificarlo
Hola Sergio,
Antes que nada te mando una extensa felicitación por el tutorial tan detallado que expusiste, mismo que ya comparti con varios compañeros del trabajo y estamos comenzando a desarrollar aplicaciones muy rápidas gracias a Python.
Mi duda es la siguiente … yo en una vista dentro de mi proceso necesito regresar codigo HTML ejemplo
def ejemploVista(resquest):
variable = ‘Mensaje Mensaje2Mensaje3’
return render_to_response(‘vista.html’,{‘ejemplo’:variable})
Aqui el detalle es que cuando veo mi resultado ya montado en la plantilla lo renderea de la siguiente manera
Mensaje1<br>Mensaje2<br>Mensaje3<br>
En pocas palabras me transforma las etiquetas HTML en su equivalente y yo deseo que conserve las entidades HTML, es necesario activar alguna librearía o modificar algo en settings para que no realice este cambio y solucionarlo
Saludos
El post conviertio ….. el texto pero la salida que da es
Mensaje1& lt;br& gt;Mensaje2& lt;br& gt;Mensaje& lt;br& gt;
Estimado, al momento en el que dices “Y vamos a la dirección:
http://127.0.0.1:8000/sobre/”
Todavía no se ve el import “from django.http import HttpResponse” en el view.py entonces si vamos a
“http://127.0.0.1:8000/sobre/” obtenemos la siguiente excepcion:
“Exception Value:
global name ‘HttpResponse’ is not defined”
Así que para todos los que están teniendo esa excepcion , solo pongan esa linea en los imports y podrán continuar al pie el curso. Me di cuenta igual que en la imagen FINAL de views.py se encuentra el import, pero no lo mencionas antes de ir a “/Sobre/” 😉
Lo comento con el fin de que si alguien le pasa, aca tiene la solución . Muy bueno el tutorial!
Saludos desde Arg.
Guahooo que maravilloso tutorial este muchas gracias ,
solo un apregunta tengo problemas al abrir ka ultima parte de detalla de las recetas y dice lo siguiente
TypeError at /receta/2
int() argument must be a string or a number, not ‘list’
y me remarca la linea de codigo
comentarios = Comentario.objects.filter(receta = dato)
si alguien a tenido y solucionado este problema podrian compartir comigo dicha soluciones
de ante mano muchas gracuas por todo …!!!!
Tengo una duda, la opcion {{receta.usuario}} me imprime directamente el nombre del user este caso el nombre con el cual hace login, pero si yo quiero que me muestre el nombre con el apellido como logro hacerlo?
Muchas gracias Sergio por toda esta ayuda. Tengo una duda, las imagenes no se muestran, ¿en que formato deben de estar?
Tan sólo quería agradecer a Sergio el tiempo y la dedicación al compartir sus conocimientos con nosotros a través de este excelente tutorial.
Leandro, no sé si ya resolviste tu duda, pero es muy posible que te haya sucedido lo mismo que a mí. Aquí va la solución (que está en un comentario anterior):
En el archivo ‘setings.py’ buscar la línea que dice
MEDIA_URL = ‘ ‘ (linea 58 aprox)
y dejarla de la siguiente manera:
MEDIA_URL = ‘ /media/’
eso es todo, espero te sirva
Hola tengo un error con las imagenes ya que estas no se cargan, la variable MEDIA_URL no arroja nada, y esta tiene el valor de ‘/media/’ , no se por que no funciona. ¿Alguna sugerencia? Saludos