django

el curso
Día 3

Temario

Vistas
● ●

Patrones de vistas HttpResponse objects lenguaje RequestContext y Contextos agregar funcionalidad modificar queryset inicial

Plantillas
● ●

Managers
● ●

AJAX y Serialización

Vistas

Una función “callback” en python asociada a un url. Respuesta puede ser: contenidos html, redirección, 404, xml, etc. Pueden “vivir” en cualquier lado, pero tienen que estar en el PythonPath. Siempre devuelven una instancia HttpResponse o una subclase de HttpResponse.
3

Vistas
# en urls.py (r'^example/project/(?P<project_id>\d+)/$',  'example_get_project') # en views.py def example_get_project (request, project_id):     try:         p = Project.objects.get(project__pk=project_id) # pk  synonym of id         html = ("<html> <body>"                 "<p> Project Name: %s </p>"                 "<p> Project Description: %s </p>"                 "</body> </html>") % (p.name, p.description)      except Project.DoesNotExist:         html = "<html> <body> <p> <b> Bu! :­( No existe! <b>  <p> </body> <html>"             return HttpResponse(html)
4

 HttpResponseNotFound def example_get_project (request.http import HttpResponse.description)  return HttpResponse(html)       except Project. p.objects.name.DoesNotExist:         html = "<html> <body> <p> <b>"                "Bu! :­( No existe!"                "<b> <p> </body> <html>"         return HttpResponseNotFound(html)         5      . project_id):     try:         p = Project.Vistas from django.get(project__pk=project_id) # pk synonym  of id         html = ("<html> <body>"                 "<p> Project Name: %s </p>"                 "<p> Project Description: %s </p>"                 "</body> </html>") % (p.

get(project__pk=project_id) # pk synonym  of id         html = ("<html> <body>"                 "<p> Project Name: %s </p>"                 "<p> Project Description: %s </p>"                 "</body> </html>") % (p. from django. Http404 def example_get_project (request. project_id):     try:         p = Project.description)  return HttpResponse(html)       except Project.Vistas ➔ 404 común.objects.http import HttpResponse. p.DoesNotExist:         raise Http404         6 .name. buena idea tener una página de error estándar.

get(pk=project_id)         t = loader.get_template('project_details. pk=project_id)     return render_to_response('project_details'. project_id):     try:         p = Project.Vistas ➔ utilizando plantillas def example_get_project_with_template (request.DoesNotExist:         raise Http404 ➔ funciones que se extienden a través de varias capas 7 def example_get_project_with_get_object (request.html')         c = Context({'project': p})         r = HttpResponse(t.render(c).objects. project_id)     p = get_object_or_404(Project. { 'project' : p }) .             mimetype="application/xhtml+xml")         return r     except Project.

http import HttpResponse In [2]: response = HttpResponse() In [3]: response. que devuelvan strings. Si se inicializo con un iterador.. Se puede utilizar como un archivo.Vistas ➔ Es la responsabilidad del programador devolver en cada vista un HttpResponse. ➔ In [1]: from django.. In [5]: response['X­DJANGO'] = 'It is the best' In [6]: response['X­DJANGO'] Out[6]: 'It is the best' ➔ Se pueden pasar iteradores.. no se puede usar como un archivo.write("<p>Here's the text of the Web page..</p>") ➔ Se pueden modificar los headers. 8 .

getvalue()     return def csv_log(request. project_id. filename='   'tasklogs'                                        '­for­%s.     response = HttpResponse(_gen(queryset).import csv.writerow(item. StringIO def _gen(qset):     io = StringIO.StringIO()         writer = csv.get_csv_row())         yield io.getvalue()     for item in qset:         io = StringIO.writerow(TaskLog.header_row) # Add header     yield io.writer(io)         writer.writer(io)     writer. username):     . mimetype='text/csv')     response['Content­Disposition'] = ('attachment..StringIO()     writer = csv..csv') % username     return response 9 .

 domain=None) HttpResponse. value) HttpResponse.__delitem__(header) HttpResponse. max_age=None.__init__(content=''.delete_cookie(key. mimetype=None.content Métodos HttpResponse.has_header(header) HttpResponse.set_cookie(key. path='/'.__setitem__(header.__getitem__(header) HttpResponse.  content_type=DEFAULT_CONTENT_TYPE) HttpResponse. domain=None. secure=None) HttpResponse. value=''.tell() 10 .Atributos HttpResponse.flush() HttpResponse.write(content) HttpResponse. path='/'. status=200.  expires=None.

class HttpResponseRedirect class HttpResponsePermanentRedirect class HttpResponseNotModified class HttpResponseBadRequest class HttpResponseNotFound class HttpResponseForbidden class HttpResponseNotAllowed class HttpResponseGone class HttpResponseServerError 11 .

'Tarea'.Vistas ➔ Ejercicio: crear una vista que devuelva un CSV con cuantas horas hizo cada usuario por tarea. 'Horas' 12 . Algo así: 'Usuario'.

CSV. XML. ú otros formatos de texto. con variables.Plantillas ➔ Documento de texto (python string) del cual podemos generar HTML. etiquetas (tags) y filtros (filters) variables son remplazadas por valores las etiquetas nos permiten controlar la logica de las plantillas filtros permiten modificar el valor de las variables 13 ➔ ➔ ➔ ➔ . Lenguaje.

 {{ name }}") In [6]: print t <django.template.Template object at 0x87c7aec> In [8]: from django.template import Context # Una vez compilada podemos renderizar con un contexto In [9]: c = Context({'name' : 'World'}) In [10]: t.render(c) Out[10]: u'Hello. World' 14 .template import Template # Parsear código de Templates y generar una instancia In [4]: t = Template("Hello.Plantillas In [1]: from django.

name }} {% endblock title %} {% block content %} Variable.html" %} {% block title %} Un proyecto: {{ project. TEMPLATE_STRING_IF_INVALI <p> <b> Un proyecto: </b> </p> D <hr/> <p> Nombre: {{ project.Etiqueta que define un bloque que se puede sobre escribir.) se accede a los atributos de la variable. el punto (.name|upper }} </p> Filtro. módifica el <p> Descripción: {{ project.description|truncatewords:"10" }} </p> string. diccionario. Plantillas Indica de que template hereda {% extends "base_for_examples. letras mayúsculas {% endblock content %} 15 . Herencia. llamada a una función sin arg.

render(c) Out[17]: u'Yo me llamo PEREZ y soy astronauta' ➔ Varios filtros definidos.ocupacion }}') In [14]: c = Context({'dict' : b}) In [15]: t. Context In [12]: b = { 'apellido' :'Perez'.template import Template.ocupacion }}') In [17]: t.apellido|upper }} y soy  {{ dict. 'ocupacion' : 'astronauta' } In [13]: t = Template('Yo me llamo {{ dict.render(c) Out[15]: u'Yo me llamo Perez y soy astronauta' In [16]: t = Template('Yo me llamo {{ dict.apellido }} y soy  {{ dict. y se pueden definir propios 16 .Plantillas In [1]: from django.

2 ➔ ➔ ➔ ➔ ➔ length safe slugify 17 .Plantillas ➔ add cut {{ value|add:"2" }} ➔ ➔ default escape floatformat 34.23234.34.{{ value|floatformat }}.

all %}              <li>               <a href="#" onclick="retrieve_tasklogs({{ task.task_set.id }})">                  {{ task.name}}</a>              <ul>              {% for task in project.name }}              </a>              </li>              {% endfor %}              </ul>           </li>         {% endfor %}     {% else %} <li> <a class="head" href='#'> No projects in database </a>             Please add some projects in the database         </li> 18     {% endif %} .Plantillas    {% if project_list %}         {% for project in project_list %}      <li>      <a class="head" href='#'>{{project.

id comment.user_id %} ..Plantillas ➔ {% cycle 'row1' 'row2' %} {% autoescape off %} {{ whatever }} {% autoescape %} {# comment #} {% ifequal user.some_view arg1.to.arg2.name1=value1 %} {% with %} http://docs. {% endifequal  %} {% include "foo/bar.com/en/dev/ref/templates/built ins/ 19 ➔ ➔ ➔ ➔ ➔ ➔ ➔ ➔ .djangoproject.html" %} {% load %} {% url path.

org/TR/html4/loose.01 Transitional//EN"                      "http://www.Plantillas ➔ Herencia / Extensión <!DOCTYPE HTML PUBLIC "­//W3C//DTD HTML 4.dtd"> <html> <head> {% block title %}     Titulo {% endblock title %} </head> <body> {% block content %}     Aquí el contenido de la página {% endblock content %} </body> </html> 20 .w3.

Plantillas {% extends "base_for_examples.description|truncatewords:"10" }} </p> {% endblock content %} 21 .html" %} {% block title %} Un proyecto: {{ project.name }} {% endblock title %} {% block content %} {% block.super %} <p> <b> Un proyecto: </b> </p> <hr/> <p> Nombre: {{ project.name|upper }} </p> <p> Descripción: {{ project.

Plantillas ➔ http://localhost:8000/timetracker/example/project­with­ shortcuts/1/ <!DOCTYPE HTML PUBLIC "­//W3C//DTD HTML 4. curse! </p> </body> </html> 22 .w3.dtd"> <html> <head> <title> Un proyecto: Curso Django </title> </head> <body>     Pagina de la Aplicación: TimeTracker <p> <b> Un proyecto: </b> </p> <hr/> <p> Nombre: CURSO DJANGO </p> <p> Descripción: curso. curso.org/TR/html4/loose.01 Transitional//EN"                      "http://www.

pop() Out[29]: {'foo': 'second level'} In [30]: c['foo'] Out[30]: 'first level' In [31]: c.context.template.push() Out[25]: {} In [26]: c['foo'] = 'second level' In [27]: c['foo'] Out[27]: 'second level' In [28]: c Out[28]: [{'foo': 'second level'}. {'foo': 'first level'}] In [29]: c.Plantillas ➔ Contextos In [23]: c = Context() In [24]: c['foo'] = 'first level' In [25]: c.pop() ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ <class 'django.ContextPopException'> 23 .

                       [ip_address_processor]) 24 . Se le pueden agregar preprocesadores al instanciarlos ➔ ➔ def ip_address_processor(request):     return {'ip_address':  request. {'foo': 'bar'.}..META['REMOTE_ADDR']} def some_view(request):     # .Plantillas ➔ RequestContext (subclase de Context) ➔ Toma como un argumento Request Agrega variables al contexto según los “Preprocesadores del Contexto” indicados por TEMPLATE_CONTEXT_PROCESSORS.     c = RequestContext(request..

context_processors.media django.core.core.context_processors.i18n ● ● django.core.Plantillas ● django.context_processors. devuelve un dict 25 .debug ● ● django.context_processors.request crear un propio: ● ● ● función python.context_processors.auth ● Agrega permisos {{perms}}.core. {{ LANGUAGE_CODE }} ● django.core. usuario {{ user }} Información de Debug {{ sql_queries }}. {{ debug }} {{ LANGUAGES }}. toma un argumento.

core.     "django.Plantillas ➔ Ejemplo TEMPLATE_CONTEXT_PROCESSORS = (     "django.context_processors.     "django. ) # ­­­ request preprocessor / en views def add_next_url (request):     return { 'next_url' : request.context_processors.     "django.add_next_url".GET.get('next'.core.auth".     "timetracker.context_processors.core.media".debug".core.context_processors.i18n".views.  None) } 26 .

    return render_to_response( 'my_template.       my_data_dictionary.       context_instance=RequestContext(request)       ) 27 .Plantillas ➔ Pasando un instancia de contexto def some_view(request):     # ...html'.

28 .Plantillas ➔ Ejercicio: Crear vistas y plantillas para ver los detalles de un proyecto. Los proyectos se deben listar como tabla y cada se deben diferenciar las filas impares de las pares con algún color.

all() Out[2]: [<Project: Curso Django>.objects.filter(name='Curso Django') Out[5]: [<Project: Curso Django>] 29 .objects. <Project: Eff>] In [5]: Project.models import Project In [2]: Project.Managers ➔ Interfaz que provee las operaciones de consulta a la base de datos In [1]: from timetracker.

 test and fix views>.Managers ➔ objects puede ser renombrado en cada modelo In [7]: from timetracker.all() .tasks.Model): <type 'exceptions.AttributeError'>: type object  ..objects.. Out[9]: [<Task: edit templates.. 'Task' has no attribute 'objects' class Task (TimeTrackerBaseModel): In [9]: Task..db import models In [8]: Task..models import Task from django. class TimeTrackerBaseModel (models.Manager() 30 ..  <Task: crear algunas vistas>]     tasks = models.all() .

Managers ➔ Se pueden usar Manager modificados extendiendo la clase Manager é instanciando en el modelo. Agregar nuevos métodos. 31 ➔ ➔ ➔ . Modificar el QuerySet inicial de los Managers Nota: Es el método sugerido para agregar funcionalidad a nivel de las tablas.

owner_id = 1.execute("""             SELECT COUNT(*)             FROM timetracker_task              WHERE timetracker_task.Managers ➔ Agregar nuevos métodos. class TaskManager (models.count() class Task (TimeTrackerBaseModel):     .filter(owner__username='admin').Manager):     def admin_task_count(self):         from django.cursor()         cursor..             """)         return cursor.db import connection         cursor = connection..     tasks = TaskManager() 32 .fetchall()[0][0]     def query_admin_task_count(self):         return self.

Managers ➔ Agregar nuevos métodos.tasks.tasks.tasks. <Task:  crear algunas vistas>] In [4]: Task. In [2]: from timetracker.admin_task_count() Out[4]: 2 In [5]: Task.query_admin_task_count() Out[5]: 2 33 .all() Out[3]: [<Task: edit templates. test and fix views>.models import Task In [3]: Task.

Manager):     def get_query_set(self):         return super(CompletedTaskManager.get_query_set().exclude(state=30) class CompletedTaskManager (models. self)\                 .get_query_set()..Manager):     def get_query_set(self):         return super(UncompletedTaskManager.filter(state=30) # Importante el primer Manager que Django encuentra es el  # default class Task (TimeTrackerBaseModel):     .Managers ➔ Modificar el QuerySet inicial de los Managers class UncompletedTaskManager (models.     tasks = TaskManager()     uncompleted_tasks = UncompletedTaskManager()     completed_tasks = CompletedTaskManager() 34 . self)\                 ..

models import Task In [2]: Task. <Task:  crear algunas vistas>] ➔ Ejercicio: crear/editar un Manager con una función que devuelve el promedio de horas para cada usuario 35 . test and fix views>] In [4]: Task. test and fix views>.uncompleted_tasks.tasks.all() Out[2]: [<Task: crear algunas vistas>] In [3]: Task.all() Out[3]: [<Task: edit templates.all() Out[4]: [<Task: edit templates.completed_tasks.Managers ➔ Modificar el QuerySet inicial de los Managers In [1]: from timetracker.

➔ Managers definidos en una clase abstracta se heredan. ➔ ➔ El default Manager es el primero que está definido en la clase. Se supone que en general los managers son particulares para la clase. relacionados. use_for_related_fields = True.Managers Managers que estén definidos en clases no abstractas no se heredan. indica que use el Manager para obj. el primero en la clase abstracta. dentro de ➔ la clase del Manager. 36 . si no. si no Django genera uno.

Un poco de AJAX y un poco de Serialización 37 .

       'django.*)$'. ) ➔ ➔ ➔ 38 .static.           (r'^resources/(?P<path>.AJAX ➔ Asynchronous Javascript and XML Utilizamos un framework: jQuery Necesitamos servir javascript. urlpatterns += patterns(''.views.       dict(document_root=media_root.             show_indexes=True)).serve'.

          dataType: "html".js"> </script> {% block script %}     function get_project_tasks(url) {         $.ajax({           type: "GET". }         }).append(html).     } {% endblock script %} 39 .           url: url.AJAX ➔ Ejemplo: buscar html generado por una vista <!­­ En la platilla base ­­> <script type="text/javascript" src="/timetracker/resources/js/jquery.           success: function(html){                               $("#id_tasks_set").empty().

                               { 'project' : p. ­­> {% endfor %} <ul> 40 .task_set.                                       { 'tasks' : tasks })         else:             return\             render_to_response('project_with_tasks_details. project_id):          if request.. plin .html'. plin. pk=project_id)                 tasks = p.method == 'GET':         p = get_object_or_404(Project.is_ajax(): # HTTP_X_REQUESTED_WITH    # with string 'XMLHttpRequest'             return render_to_response('task_details_ajax.start_date }} </li>         <!­­ plin.AJAX def example_ajax_get_task_for_project (request.html'.name }} </li>         <li> Descripción: {{ task.all()         if request. 'tasks' : tasks }) <!­­ La plantilla ­­> <ul> {% for task in tasks %}         <li> Nombre: {{ task.description }} </li>         <li> Fecha de Inicio: {{ task.

core import serializers In [12]: data=serializers. data):    .:      <DeserializedObject: Curso Django> <class  'django.Project.:     print obj.0"><object pk="1" model="timetracker.deserialize("xml"..project"><field  type="CharField" name="name">Curso Django</field></object></django­ objects> In [18]: for obj in serializers.serializers..:         .objects..core.base..DeserializedObject'> 41 .)) In [17]: data Out[17]: '<?xml version="1.serialize("xml".filter(pk=1)... type(obj)    .Serialización In [11]: from django.  fields=('name'...0" encoding="utf­8"?>\n<django­objects  version="1..

 stream=out) ➔ for deserialized_object in serializers.getvalue() ➔ se puede serializar a un archivo se pueden salvar objetos 'deserializados' out = open("file.Serialización ➔ se pueden instanciar. data):     if object_should_be_saved(deserialized_object):         deserialized_object..deserialize("xml".serialize(SomeModel.serialize(queryset) data = xml_serializer.get_serializer("xml") xml_serializer = XMLSerializer() xml_serializer. XMLSerializer = serializers.save() 42 .all().objects. "w") xml_serializer.xml"..

serialize(queryset.get_serializer("json")() json_serializer.AJAX y Serialización json_serializer = serializers. ensure_ascii=False.  stream=response) ➔ Ejercicio: crear una vista serialize los TaskLog y los muestre cada vez que se pidan utilizando AJAX 43 .

USA. To view a copy of this license. San Francisco. Suite 300.org/licenses/by-nc-sa/2.This work is licensed under the Creative Commons Attribution-NoncommercialShare Alike 2. visit http://creativecommons.5/ar/ or send a letter to Creative Commons. California. 44 . 94105. 171 Second Street.5 Argentina License.

Sign up to vote on this title
UsefulNot useful