Post on 16-Apr-2017
django
el curso
Da 3
Vistas
Patrones de vistas
HttpResponse objects
Plantillas
lenguaje
RequestContext y Contextos
Managers
agregar funcionalidad
modificar queryset inicial
AJAX y Serializacin
Temario
Vistas
Una funcin callback en python asociada a un url.
Siempre devuelven una instancia HttpResponse o una subclase de HttpResponse.
Respuesta puede ser: contenidos html, redireccin, 404, xml, etc.
Pueden vivir en cualquier lado, pero tienen que estar en el PythonPath.
# en urls.py(r'^example/project/(?P\d+)/$', 'example_get_project')
# en views.pydef example_get_project (request, project_id): try:
p = Project.objects.get(project__pk=project_id) # pk synonym of id
html = (" " " Project Name: %s " " Project Description: %s " " ") %
(p.name, p.description) except Project.DoesNotExist: html = "
Bu! :-( No existe! " return HttpResponse(html)Vistasfrom
django.http import HttpResponse, HttpResponseNotFounddef
example_get_project (request, project_id): try: p =
Project.objects.get(project__pk=project_id) # pk synonym of id html
= (" " " Project Name: %s " " Project Description: %s " " ") %
(p.name, p.description) return HttpResponse(html) except
Project.DoesNotExist: html = " " "Bu! :-( No existe!" " " return
HttpResponseNotFound(html) Vistasfrom django.http import
HttpResponse, Http404def example_get_project (request, project_id):
try: p = Project.objects.get(project__pk=project_id) # pk synonym
of id html = (" " " Project Name: %s " " Project Description: %s "
" ") % (p.name, p.description) return HttpResponse(html) except
Project.DoesNotExist: raise Http404 404 comn, buena idea tener una
pgina de error estndar.Vistasdef 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="application/xhtml+xml") return r except
Project.DoesNotExist: raise Http404def
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 travs de varias capasutilizando
plantillasVistasEs la responsabilidad del programador devolver en
cada vista un HttpResponse.VistasSe puede utilizar como un
archivo...In [1]: from django.http import HttpResponseIn [2]:
response = HttpResponse()In [3]: response.write("Here's the text of
the Web page.")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, StringIOdef
_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() returndef csv_log(request, project_id, username): ...
response = HttpResponse(_gen(queryset), mimetype='text/csv')
response['Content-Disposition'] = ('attachment; filename='
'tasklogs'
'-for-%s.csv') % username return
responseAtributosHttpResponse.contentMtodosHttpResponse.__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
HttpResponseRedirectclass HttpResponsePermanentRedirectclass
HttpResponseNotModifiedclass HttpResponseBadRequestclass
HttpResponseNotFoundclass HttpResponseForbiddenclass
HttpResponseNotAllowedclass HttpResponseGoneclass
HttpResponseServerErrorVistasEjercicio: crear una vista que
devuelva un CSV con cuantas horas hizo cada usuario por tarea. Algo
as: 'Usuario', 'Tarea', 'Horas'PlantillasDocumento 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 valoreslas etiquetas nos
permiten controlar la logica de las plantillasfiltros permiten
modificar el valor de las variablesIn [1]: from django.template
import Template# Parsear cdigo de Templates y generar una
instanciaIn [4]: t = Template("Hello, {{ name }}")In [6]: print tIn
[8]: from django.template import Context# Una vez compilada podemos
renderizar con un contextoIn [9]: c = Context({'name' : 'World'})In
[10]: t.render(c)Out[10]: u'Hello, World'Plantillas{% extends
"base_for_examples.html" %}{% block title %}Un proyecto: {{
project.name }}{% endblock title %}{% block content %} Un proyecto:
Nombre: {{ project.name|upper }} Descripcin: {{
project.description|truncatewords:"10" }} {% endblock content
%}Variable, el punto (.) se accede a los atributos de la variable,
diccionario, llamada a una funcin sin arg.Etiqueta que define un
bloque que se puede sobre escribir. Herencia.Filtro, mdifica el
string, letras maysculas Indica de que template
heredaPlantillasTEMPLATE_STRING_IF_INVALIDIn [1]: from
django.template import Template, ContextIn [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
propiosPlantillasPlantillasadd {{ value|add:"2"
}}cutdefaultescapefloatformat 34.23234,{{ value|floatformat
}},34.2lengthsafeslugify {% if project_list %} {% for project in
project_list %} {{project.name}} {% for task in
project.task_set.all %} {{ task.name }} {% endfor %} {% endfor %}
{% else %} No projects in database Please add some projects in the
database {% endif %}Plantillas{% cycle 'row1' 'row2' %}{%
autoescape off %} {{ whatever }} {% autoescape %}{# comment #}{%
ifequal user.id comment.user_id %} .. {% endifequal %}{% include
"foo/bar.html" %}{% load %}{% url path.to.some_view
arg1,arg2,name1=value1 %}{% with
%}http://docs.djangoproject.com/en/dev/ref/templates/builtins/Plantillas{%
block title %} Titulo{% endblock title %}{% block content %} Aqu el
contenido de la pgina{% endblock content %}PlantillasHerencia /
Extensin{% extends "base_for_examples.html" %}{% block title %}Un
proyecto: {{ project.name }}{% endblock title %}{% block content
%}{% block.super %} Un proyecto: Nombre: {{ project.name|upper }}
Descripcin: {{ project.description|truncatewords:"10" }} {%
endblock content %}PlantillasUn proyecto: Curso Django Pagina de la
Aplicacin: TimeTracker Un proyecto: Nombre: CURSO DJANGO
Descripcin: curso, curso, curse!
Plantillashttp://localhost:8000/timetracker/example/project-with-shortcuts/1/PlantillasContextosIn
[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]: cOut[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()-----------------------------------------------------PlantillasRequestContext
(subclase de Context)Toma como un argumento RequestAgrega variables
al contexto segn los Preprocesadores del Contexto indicados por
TEMPLATE_CONTEXT_PROCESSORS.Se le pueden agregar preprocesadores al
instanciarlosdef 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.authAgrega permisos {{perms}},
usuario {{ user }} django.core.context_processors.debugInformacin
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:funcin
python, toma un argumento, devuelve un
dictPlantillasTEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"timetracker.views.add_next_url",)# --- request preprocessor / en
viewsdef add_next_url (request): return { 'next_url' :
request.GET.get('next', None) }Ejemplodef some_view(request): # ...
return render_to_response('my_template.html',
my_data_dictionary,
context_instance=RequestContext(request) )PlantillasPasando un
instancia de contextoPlantillasEjercicio: 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 algn color.ManagersInterfaz que provee las operaciones de
consulta a la base de datos In [1]: from timetracker.models import
ProjectIn [2]: Project.objects.all()Out[2]: [, ]In [5]:
Project.objects.filter(name='Curso Django')Out[5]:
[]Managersobjects puede ser renombrado en cada modelo from
django.db import modelsclass TimeTrackerBaseModel
(models.Model):...class Task (TimeTrackerBaseModel):... tasks =
models.Manager()In [7]: from timetracker.models import TaskIn [8]:
Task.objects.all()...: type object 'Task' has no attribute
'objects'In [9]: Task.tasks.all()Out[9]: [, ]ManagersSe pueden usar
Manager modificados extendiendo la clase Manager instanciando en el
modelo.Nota: Es el mtodo sugerido para agregar funcionalidad a
nivel de las tablas.Agregar nuevos mtodos.Modificar el QuerySet
inicial de los ManagersManagersAgregar nuevos mtodos.class
TaskManager (models.Manager): def admin_task_count(self): from
django.db import connection cursor = connection.cursor()
cursor.execute(""" SELECT COUNT(*) FROM timetracker_task WHERE
timetracker_task.owner_id = 1; """) return cursor.fetchall()[0][0]
def query_admin_task_count(self): return
self.filter(owner__username='admin').count()class Task
(TimeTrackerBaseModel): ... tasks = TaskManager()ManagersAgregar
nuevos mtodos.In [2]: from timetracker.models import TaskIn [3]:
Task.tasks.all()Out[3]: [, ]In [4]:
Task.tasks.admin_task_count()Out[4]: 2In [5]:
Task.tasks.query_admin_task_count()Out[5]: 2Managersclass
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 # defaultclass Task (TimeTrackerBaseModel):
... tasks = TaskManager() uncompleted_tasks =
UncompletedTaskManager() completed_tasks =
CompletedTaskManager()Modificar el QuerySet inicial de los
ManagersManagersIn [1]: from timetracker.models import TaskIn [2]:
Task.uncompleted_tasks.all()Out[2]: []In [3]:
Task.completed_tasks.all()Out[3]: []In [4]: Task.tasks.all()Out[4]:
[, ]Modificar el QuerySet inicial de los ManagersEjercicio:
crear/editar un Manager con una funcin que devuelve el promedio de
horas para cada usuarioManagersManagers que estn 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
SerializacinAJAXUtilizamos un framework: jQueryAsynchronous
Javascript and XMLurlpatterns += patterns('',
(r'^resources/(?P.*)$',
'django.views.static.serve',
dict(document_root=media_root,
show_indexes=True)),
)Necesitamos servir javascript.AJAXEjemplo: buscar html generado
por una vista{% block script %} function get_project_tasks(url) {
$.ajax({ type: "GET", url: url, dataType: "html", success:
function(html){ $("#id_tasks_set").empty().append(html); } }); }{%
endblock script %}
AJAXdef 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 }){% for task in tasks %}
Nombre: {{ task.name }} Descripcin: {{ task.description }} Fecha de
Inicio: {{ task.start_date }} {% endfor %}SerializacinIn
[11]: from django.core import serializersIn [12]:
data=serializers.serialize("xml",Project.objects.filter(pk=1),
fields=('name',))In [17]: dataOut[17]: '\nCurso DjangoIn [18]: for
obj in serializers.deserialize("xml", data): ....: print obj,
type(obj) ....: ....: Serializacinse pueden salvar objetos
'deserializados'se puede serializar a un archivose pueden
instanciar...out = open("file.xml",
"w")xml_serializer.serialize(SomeModel.objects.all(),
stream=out)XMLSerializer =
serializers.get_serializer("xml")xml_serializer =
XMLSerializer()xml_serializer.serialize(queryset)data =
xml_serializer.getvalue()for deserialized_object in
serializers.deserialize("xml", data): if
object_should_be_saved(deserialized_object):
deserialized_object.save()AJAX y SerializacinEjercicio: crear una
vista serialize los TaskLog y los muestre cada vez que se pidan
utilizando AJAXjson_serializer =
serializers.get_serializer("json")()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.