Curso de Django | Django Course
Upcoming SlideShare
Loading in...5
×
 

Curso de Django | Django Course

on

  • 4,532 views

Django course given while working at Except. In spanish.

Django course given while working at Except. In spanish.

Statistics

Views

Total Views
4,532
Views on SlideShare
4,517
Embed Views
15

Actions

Likes
2
Downloads
71
Comments
1

2 Embeds 15

http://www.slideshare.net 14
http://localhost:8080 1

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

11 of 1

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Curso de Django | Django Course Curso de Django | Django Course Presentation Transcript

    • django el curso Día 3
      • Vistas
          • Patrones de vistas
          • HttpResponse objects
      • Plantillas
          • lenguaje
          • RequestContext y Contextos
      • Managers
          • agregar funcionalidad
          • modificar queryset inicial
      • AJAX y Serialización
      Temario
    • Vistas
        • Una función “callback” en python asociada a un url.
        • Siempre devuelven una instancia HttpResponse o una subclase de HttpResponse.
        • Respuesta puede ser: contenidos html, redirección, 404, xml, etc.
        • Pueden “vivir” en cualquier lado, pero tienen que estar en el PythonPath.
    • # 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 = ( &quot;<html> <body>&quot; &quot;<p> Project Name: %s </p>&quot; &quot;<p> Project Description: %s </p>&quot; &quot;</body> </html>&quot; ) % (p.name, p.description) except Project.DoesNotExist: html = &quot;<html> <body> <p> <b> Bu! :-( No existe! <b> <p> </body> <html>&quot; return HttpResponse(html) Vistas
    • from django.http import HttpResponse, HttpResponseNotFound def example_get_project (request, project_id): try : p = Project.objects.get(project__pk=project_id) # pk synonym of id html = ( &quot;<html> <body>&quot; &quot;<p> Project Name: %s </p>&quot; &quot;<p> Project Description: %s </p>&quot; &quot;</body> </html>&quot; ) % (p.name, p.description) return HttpResponse(html) except Project.DoesNotExist: html = &quot;<html> <body> <p> <b>&quot; &quot;Bu! :-( No existe!&quot; &quot;<b> <p> </body> <html>&quot; return HttpResponseNotFound(html ) Vistas
    • from django.http import HttpResponse, Http404 def example_get_project (request, project_id): try : p = Project.objects.get(project__pk=project_id) # pk synonym of id html = ( &quot;<html> <body>&quot; &quot;<p> Project Name: %s </p>&quot; &quot;<p> Project Description: %s </p>&quot; &quot;</body> </html>&quot; ) % (p.name, p.description) return HttpResponse(html) except Project.DoesNotExist: raise Http404
        • 404 común, buena idea tener una página de error estándar.
      Vistas
    • def example_get_project_with_template (request, project_id): try : p = Project.objects.get(pk=project_id) t = loader.get_template('project_details.html') c = Context({'project': p}) r = HttpResponse(t.render(c), mimetype=&quot;application/xhtml+xml&quot;) return r except Project.DoesNotExist: raise Http404 def example_get_project_with_get_object (request, project_id) p = get_object_or_404(Project, pk=project_id) return render_to_response('project_details', { 'project' : p })
        • funciones que se extienden a través de varias capas
        • utilizando plantillas
      Vistas
        • Es la responsabilidad del programador devolver en cada vista un HttpResponse.
      Vistas
        • Se puede utilizar como un archivo...
      In [1]: from django.http import HttpResponse In [2]: response = HttpResponse() In [3]: response.write(&quot;<p>Here's the text of the Web page.</p>&quot;)
        • Se pueden modificar los headers...
      In [5]: response['X-DJANGO'] = 'It is the best' In [6]: response['X-DJANGO'] Out[6]: 'It is the best'
        • Se pueden pasar iteradores, que devuelvan strings. Si se inicializo con un iterador, no se puede usar como un archivo.
    • import csv, StringIO def _gen(qset): io = StringIO.StringIO() writer = csv.writer(io) writer.writerow(TaskLog.header_row) # Add header yield io.getvalue() for item in qset: io = StringIO.StringIO() writer = csv.writer(io) writer.writerow(item.get_csv_row()) yield io.getvalue() return def csv_log(request, project_id, username): ... response = HttpResponse(_gen(queryset), mimetype='text/csv') response[ 'Content-Disposition' ] = ( 'attachment; filename=' 'tasklogs' '-for-%s.csv' ) % username return response
    • Atributos HttpResponse.content Métodos HttpResponse.__init__(content='', mimetype=None, status=200, content_type=DEFAULT_CONTENT_TYPE) HttpResponse.__setitem__(header, value) HttpResponse.__delitem__(header) HttpResponse.__getitem__(header) HttpResponse.has_header(header) HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None) HttpResponse.delete_cookie(key, path='/', domain=None) HttpResponse.write(content) HttpResponse.flush() HttpResponse.tell()
    • class HttpResponseRedirect class HttpResponsePermanentRedirect class HttpResponseNotModified class HttpResponseBadRequest class HttpResponseNotFound class HttpResponseForbidden class HttpResponseNotAllowed class HttpResponseGone class HttpResponseServerError
    • Vistas
        • Ejercicio: crear una vista que devuelva un CSV con cuantas horas hizo cada usuario por tarea. Algo así: 'Usuario', 'Tarea', 'Horas'
    • Plantillas
      • Documento de texto (python string) del cual podemos generar HTML, CSV, XML, ú otros formatos de texto.
      • Lenguaje, con variables, 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
    • In [1]: from django.template import Template # Parsear código de Templates y generar una instancia In [4]: t = Template(&quot;Hello, {{ name }}&quot;) 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' Plantillas
    • {% extends &quot;base_for_examples.html&quot; %} {% block title %} Un proyecto: {{ project.name }} {% endblock title %} {% block content %} <p> <b> Un proyecto: </b> </p> <hr/> <p> Nombre: {{ project.name|upper }} </p> <p> Descripción: {{ project.description|truncatewords:&quot;10&quot; }} </p> {% endblock content %} Variable, el punto (.) se accede a los atributos de la variable, diccionario, llamada a una función sin arg. Etiqueta que define un bloque que se puede sobre escribir. Herencia. Filtro, módifica el string, letras mayúsculas Indica de que template hereda Plantillas TEMPLATE_STRING_IF_INVALID
    • In [1]: from django.template import Template, Context In [12]: b = { 'apellido' :'Perez', 'ocupacion' : 'astronauta' } In [13]: t = Template('Yo me llamo {{ dict.apellido }} y soy {{ dict.ocupacion }}') In [14]: c = Context({'dict' : b}) In [15]: t.render(c) Out[15]: u'Yo me llamo Perez y soy astronauta' In [16]: t = Template('Yo me llamo {{ dict.apellido|upper }} y soy {{ dict.ocupacion }}') In [17]: t.render(c) Out[17]: u'Yo me llamo PEREZ y soy astronauta'
      • Varios filtros definidos, y se pueden definir propios
      Plantillas
    • Plantillas
      • add {{ value|add:&quot;2&quot; }}
      • cut
      • default
      • escape
      • floatformat 34.23234,{{ value|floatformat }},34.2
      • length
      • safe
      • slugify
    • {% if project_list %} {% for project in project_list %} <li> <a class=&quot;head&quot; href='#'>{{project.name}}</a> <ul> {% for task in project.task_set.all %} <li> <a href=&quot;#&quot; onclick=&quot;retrieve_tasklogs({{ task.id }})&quot;> {{ task.name }} </a> </li> {% endfor %} </ul> </li> {% endfor %} {% else %} <li> <a class=&quot;head&quot; href='#'> No projects in database </a> Please add some projects in the database </li> {% endif %} Plantillas
      • {% cycle 'row1' 'row2' %}
      • {% autoescape off %} {{ whatever }} {% autoescape %}
      • {# comment #}
      • {% ifequal user.id comment.user_id %} .. {% endifequal %}
      • {% include &quot;foo/bar.html&quot; %}
      • {% load %}
      • {% url path.to.some_view arg1,arg2,name1=value1 %}
      • {% with %}
      • http://docs.djangoproject.com/en/dev/ref/templates/builtins/
      Plantillas
    • <!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;> <html> <head> {% block title %} Titulo {% endblock title %} </head> <body> {% block content %} Aquí el contenido de la página {% endblock content %} </body> </html> Plantillas
      • Herencia / Extensión
    • {% extends &quot;base_for_examples.html&quot; %} {% 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.description|truncatewords:&quot;10&quot; }} </p> {% endblock content %} Plantillas
    • <!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;> <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, curse! </p> </body> </html> Plantillas
      • http://localhost:8000/timetracker/example/project-with-shortcuts/1/
    • Plantillas
        • Contextos
      In [23]: c = Context() In [24]: c['foo'] = 'first level' In [25]: c.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.pop() Out[29]: {'foo': 'second level'} In [30]: c['foo'] Out[30]: 'first level' In [31]: c.pop() ----------------------------------------------------- <class 'django.template.context.ContextPopException'>
    • 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.
          • Se le pueden agregar preprocesadores al instanciarlos
      def ip_address_processor(request): return {'ip_address': request.META['REMOTE_ADDR']} def some_view(request): # ... c = RequestContext(request, {'foo': 'bar',}, [ip_address_processor]) return t.render(c)
    • Plantillas
      • django.core.context_processors.auth
        • Agrega permisos {{perms}}, usuario {{ user }}
      • django.core.context_processors.debug
        • Información de Debug {{ sql_queries }}, {{ debug }}
      • django.core.context_processors.i18n
        • {{ LANGUAGES }}, {{ LANGUAGE_CODE }}
      • django.core.context_processors.media
      • django.core.context_processors.request
      • crear un propio:
        • función python, toma un argumento, devuelve un dict
    • Plantillas TEMPLATE_CONTEXT_PROCESSORS = ( &quot;django.core.context_processors.auth&quot;, &quot;django.core.context_processors.debug&quot;, &quot;django.core.context_processors.i18n&quot;, &quot;django.core.context_processors.media&quot;, &quot;timetracker.views.add_next_url&quot;, ) # --- request preprocessor / en views def add_next_url (request): return { 'next_url' : request.GET.get('next', None) }
        • Ejemplo
    • def some_view(request): # ... return render_to_response( 'my_template.html', my_data_dictionary, context_instance=RequestContext(request) ) Plantillas
        • Pasando un instancia de contexto
    • 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.
    • Managers
      • Interfaz que provee las operaciones de consulta a la base de datos
      In [1]: from timetracker.models import Project In [2]: Project.objects.all() Out[2]: [<Project: Curso Django>, <Project: Eff>] In [5]: Project.objects.filter(name='Curso Django') Out[5]: [<Project: Curso Django>]
    • Managers
      • objects puede ser renombrado en cada modelo
      from django.db import models class TimeTrackerBaseModel (models.Model): ... class Task (TimeTrackerBaseModel): ... tasks = models.Manager() In [7]: from timetracker.models import Task In [8]: Task.objects.all() ... <type 'exceptions.AttributeError'>: type object 'Task' has no attribute 'objects' In [9]: Task.tasks.all() Out[9]: [<Task: edit templates, test and fix views>, <Task: crear algunas vistas>]
    • Managers
      • Se pueden usar Manager modificados extendiendo la clase Manager é instanciando en el modelo.
      • Nota: Es el método sugerido para agregar funcionalidad a nivel de las tablas.
      • Agregar nuevos métodos.
      • Modificar el QuerySet inicial de los Managers
    • Managers
      • Agregar nuevos métodos.
      class TaskManager (models.Manager): def admin_task_count( self ): from django.db import connection cursor = connection.cursor() cursor.execute( &quot;&quot;&quot; SELECT COUNT(*) FROM timetracker_task WHERE timetracker_task.owner_id = 1; &quot;&quot;&quot; ) return cursor.fetchall()[0][0] def query_admin_task_count( self ): return self .filter(owner__username='admin').count() class Task (TimeTrackerBaseModel): ... tasks = TaskManager()
    • Managers
      • Agregar nuevos métodos.
      In [2]: from timetracker.models import Task In [3]: Task.tasks.all() Out[3]: [<Task: edit templates, test and fix views>, <Task: crear algunas vistas>] In [4]: Task.tasks.admin_task_count() Out[4]: 2 In [5]: Task.tasks.query_admin_task_count() Out[5]: 2
    • Managers class UncompletedTaskManager (models.Manager): def get_query_set(self): return super (UncompletedTaskManager, self ) .get_query_set().exclude(state=30) class CompletedTaskManager (models.Manager): def get_query_set(self): return super (CompletedTaskManager, self ) .get_query_set().filter(state=30) # Importante el primer Manager que Django encuentra es el # default class Task (TimeTrackerBaseModel): ... tasks = TaskManager() uncompleted_tasks = UncompletedTaskManager() completed_tasks = CompletedTaskManager()
        • Modificar el QuerySet inicial de los Managers
    • Managers In [1]: from timetracker.models import Task In [2]: Task.uncompleted_tasks.all() Out[2]: [<Task: crear algunas vistas>] In [3]: Task.completed_tasks.all() Out[3]: [<Task: edit templates, test and fix views>] In [4]: Task.tasks.all() Out[4]: [<Task: edit templates, test and fix views>, <Task: crear algunas vistas>]
        • Modificar el QuerySet inicial de los Managers
        • Ejercicio: crear/editar un Manager con una función que devuelve el promedio de horas para cada usuario
    • Managers
        • Managers que estén definidos en clases no abstractas no se heredan. Se supone que en general los managers son particulares para la clase.
        • Managers definidos en una clase abstracta se heredan.
        • El default Manager es el primero que está definido en la clase, si no, el primero en la clase abstracta, si no Django genera uno.
        • use_for_related_fields = True , dentro de la clase del Manager, indica que use el Manager para obj. relacionados.
    • Un poco de AJAX y un poco de Serialización
    • AJAX
      • Utilizamos un framework: jQuery
      • Asynchronous Javascript and XML
      • urlpatterns += patterns('', (r'^resources/(?P<path>.*)$', 'django.views.static.serve', dict(document_root=media_root, show_indexes=True)), )
      • Necesitamos servir javascript.
    • AJAX
      • Ejemplo: buscar html generado por una vista
      {% block script %} function get_project_tasks(url) { $.ajax({ type: &quot;GET&quot;, url: url, dataType: &quot;html&quot;, success: function(html){ $(&quot;#id_tasks_set&quot;).empty().append(html); } }); } {% endblock script %} <!-- En la platilla base --> <script type=&quot;text/javascript&quot; src=&quot;/timetracker/resources/js/jquery.js&quot;> </script>
    • AJAX def example_ajax_get_task_for_project (request, project_id): if request.method == 'GET': p = get_object_or_404(Project, pk=project_id) tasks = p.task_set.all() if request.is_ajax(): # HTTP_X_REQUESTED_WITH # with string 'XMLHttpRequest' return render_to_response('task_details_ajax.html', { 'tasks' : tasks }) else: return render_to_response('project_with_tasks_details.html', { 'project' : p, 'tasks' : tasks }) <!-- La plantilla --> <ul> {% for task in tasks %} <li> Nombre: {{ task.name }} </li> <li> Descripción: {{ task.description }} </li> <li> Fecha de Inicio: {{ task.start_date }} </li> <!-- plin, plin, plin .. --> {% endfor %} <ul>
    • Serialización In [11]: from django.core import serializers In [12]: data=serializers.serialize(&quot;xml&quot;,Project.objects.filter(pk=1), fields=('name',)) In [17]: data Out[17]: '<?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?> <django-objects version=&quot;1.0&quot;><object pk=&quot;1&quot; model=&quot;timetracker.project&quot;><field type=&quot;CharField&quot; name=&quot;name&quot;>Curso Django</field></object></django-objects> In [18]: for obj in serializers.deserialize(&quot;xml&quot;, data): ....: print obj, type(obj) ....: ....: <DeserializedObject: Curso Django> <class 'django.core.serializers.base.DeserializedObject'>
    • Serialización
      • se pueden salvar objetos 'deserializados'
      • se puede serializar a un archivo
      • se pueden instanciar...
      out = open(&quot;file.xml&quot;, &quot;w&quot;) xml_serializer.serialize(SomeModel.objects.all(), stream=out) XMLSerializer = serializers.get_serializer(&quot;xml&quot;) xml_serializer = XMLSerializer() xml_serializer.serialize(queryset) data = xml_serializer.getvalue() for deserialized_object in serializers.deserialize(&quot;xml&quot;, data): if object_should_be_saved(deserialized_object): deserialized_object.save()
    • AJAX y Serialización
        • Ejercicio: crear una vista serialize los TaskLog y los muestre cada vez que se pidan utilizando AJAX
      json_serializer = serializers.get_serializer(&quot;json&quot;)() json_serializer.serialize(queryset, ensure_ascii=False, stream=response)
    • This work is licensed under the Creative Commons Attribution-Noncommercial-Share Alike 2.5 Argentina License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.5/ar/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.