Taller Intermedio/Avanzado
autor: | Martín Gaitán |
---|---|
evento: | iSummit 2012 |
lugar: | Loja, Ecuador |
fecha: | Miércoles 24 de octubre, 2012 |
>>> 3 + 4.4, int(1j**2), 10 % 1
>>> a = [4.0, 'Hola', Posicion()] >>> a[1] == 'Hola' True >>> range(-2, 3) [-2, -1, 0, 1, 2] >>> [p.x for p in posiciones if p.y > 0]
>>> hinchada = {'Martín': 'Boca Jr', 'Ramiro': 'Barcelona', 'René': 'Barcelona'} >>> hinchada.values() # keys() ['Boca Jr', 'Barcelona', 'Barcelona']
>>> set(['Hola', 'Chau', 4, 'Chau']) set([4, 'Hola', 'Chau'])
def potenciar(n, exp=2): return n**exp # otra forma (inline) potenciar = lambda n, exp: n**exp
class MiModelo(models.Models):
class Hijo(Padre1, Padre2):
Control:
# iteracion for ticket in Tickets.object.all(): print ticket.titulo # condicional if ticket.vencimiento >= datetime.now(): alarma.sonar() else: print "todo está bien, pelado!"
class Ticket(models.Model): titulo = models.CharField(max_length=150) descripcion = models.TextField() ...
Vistas
# views.py from django.http import HttpResponse def hola_mundo(request): return HttpResponse('Hola Mundo') # urls.py from django.conf.urls import patterns, url urlpatterns = patterns('', url(r'^hola-mundo$', 'tiquetera.tickets.views.hola_mundo') )
from django.shortcuts import render, redirect def listar_tickets(request): tickets = Ticket.objects.all() return render(request, "ticket_listar.html", { "tickets": tickets })
def detalle_ticket(request, id): ticket = Ticket.objects.get(id=id) return render(request, "ticket_detalle.html", { "ticket": ticket })
urls.py relaciona direcciones con vistas
urlpatterns = patterns('', url(r'^$', 'tiquetera.tickets.views.listar_tickets', name='ticket-listado'), url(r'^ticket/(?P<id>\d+)/$', 'tiquetera.tickets.views.detalle_ticket', name='ticket-detalle'), url(r'^admin/', include(admin.site.urls)), )
<h1>Listado de Tickets</h1> <ul> {% for ticket in lista_tickets %} <li> <a href="{{ ticket.get_absolute_url }}"> {{ ticket.title|upper }} </a> </li> <p>{{ ticket.descripcion|truncatewords:"15" }}</p> {% endfor %} </ul>
{% block nombre_bloque %}
Porción que puede redefinirse
{% extends 'template_base.html' %}
Herencia. Usar otro como base y redefinir bloques
{% include 'pedacito.html' %}
Incrustar fragmentos desde otros templates
{% url nombre_url parametro1, ... %}
Construir la url mediante su nombre. Igual a reverse()
from django import forms class ContactForm(forms.Form): asunto = forms.CharField(max_length=100) mensaje = forms.CharField() remitente = forms.EmailField() cc_a_mi = forms.BooleanField(required=False)
>>> contact_form = ContactForm() >>> print contact_form.as_p() # as >>> mi_form.is_valid() # no porque está vacío! >>> datos = {'asunto': 'Curso', 'remitente': 'gaitan@gmail.com', 'mensaje': 'muy interesante'} >>> otro_form = ContactForm(datos) >>> otro_form.is_valid() # si
def contacto(request): if request.method == "POST": form = ContactForm(request.POST) if form.is_valid(): # aqui usamos los datos validos # que están en form.cleaned_data # Ejemplo: mandamos el email return redirect(...) else: form = ContactForm() return render(request, "contact.html", { "form": form, })
# en la vista from django.core.mail import send_mail send_mail('Asunto aqui', 'cuerpo del mensaje', 'remitente@ejemplo.com', ['para@ejemplo.com'], fail_silently=False) # Trampita: que envie el email a la pantalla. # en settings.py EMAIL_BACKEND = \ 'django.core.mail.backends.console.EmailBackend'
def contacto(request): data = request.POST if request.method == "POST" \ else None form = ContactForm(data) if form.is_valid(): # aqui usamos los datos validos en send_mail return redirect(...) return render(request, "contact.html", { "form": form, })
Además de las validaciones automáticas (dadas por el tipo de Field) Django soporta validaciones y "limpiezas" propias.
class ContactForm(forms.Form): ... def clean_remitente(self): dato = self.cleaned_data['remitente'] if not dato.endswith('utpl.edu.ec'): raise forms.ValidationError("Usa tu correo oficial") # acá podria manipular. pero siempre hay que devolver el dato return dato
Si el mensaje no es de René, exigir que sea largo
def clean(self): cleaned_data = super(ContactForm, self).clean() remitente = cleaned_data.get("remitente") mensaje = cleaned_data.get("mensaje") if (remitente != 'rrelizalde@utpl.edu.ec' and len(mensaje) < 50): raise forms.ValidationError( "Su mensaje es demasiado breve" \ "y usted no es René.") # Siempre devolver el diccionario # de datos limpios return cleaned_data
from django import forms from models import Ticket class TicketForm(forms.ModelForm): class Meta: model = Ticket
def editar_ticket(request, id): ticket = Ticket.objects.get(id=id) if request.method == "POST": form = TicketForm(request.POST, instance=ticket) if form.is_valid(): form.save() return redirect("ticket-detalle", id=id) else: form = TicketForm(instance=ticket) return render(request, "ticket_editar.html", { "ticket": ticket, "form": form, })
Buscar datos de la base (muchos, uno) y..
- mostrarmos a traves de un template
- editarlos con un formulario
Suena bastante típico
Recuerda: ¡No te repitas!
from django.views.generic import ListView class TicketListView(ListView): model = Ticket template_name = "ticket_listar.html" # template default: ticket_list.html context_object_name = "tickets" # default: object_list listar_tickets = TicketListView.as_view()
syncdb fallaría. Hay que usar South.
- Lo instalamos (ejemplo: pip install south)
- Agregamos south a INSTALLED_APPS
- syncdb
- manage.py convert_to_south tickets
class Ticket(models.Model): (...) vencimiento = models.DateField(null=True, blank=True)
Creamos la migracion:
$ manage.py schemamigration tickets --auto
Crea una migracion 0002_auto__add_field_ticket_vencimiento.py
La aplicamos:
$ manage.py migrate tickets
La documentación de Django es buenísima!
Pueden consultarme
Gracias por la participación!
Table of Contents | t |
---|---|
Exposé | ESC |
Full screen slides | e |
Presenter View | p |
Source Files | s |
Slide Numbers | n |
Toggle screen blanking | b |
Show/hide slide context | c |
Notes | 2 |
Help | h |