Para perfeccionistas con deadlines Leo Soto M. Imagemaker IT Encuentro Linux 2008
Python? Django?
Python is an experiment in how much freedom programmers need...
...Too much freedom and nobody can read another's code; too little and expressiveness is endangered - Guido van Rossum (Agosto 1996)
Django
Simple
Flexible
Pragmático
Models Templates
Models Forms Auth Templates
Models Forms Admin Templates Auth
Models Forms Admin Templates i18n Auth
GIS Models Forms Admin Templates i18n Auth
Comments GIS Models Forms Caching DataBrowse Admin Templates i18n Auth
Comments GIS Models Forms Caching DataBrowse Admin Auth Templates Syndication i18n Sitemaps
django-command-extensions GIS django-bookmarks Comments django-contact-form Caching django-profile Models django-registration Forms Pinax google-app-engine-django DataBrowse django-search Admin Auth django-tagging django-authopenid django-mptt django-contact-form Templates Satchmo Syndication django-timezones i18n django-jython django-photologue Sitemaps django-evolution
Eehhh...
Alto!
Código > Blabla
Proyecto: eldemo App: elinux
1. Modelos
# eldemo/elinux/models.py: from django.db import models from datetime import date class Noticia(models.Model): fecha = models.datefield( default=date.today) titulo = models.charfield(max_length=80) contenido = models.textfield()
class Expositor(models.Model): nombre = models.charfield(max_length=80, unique=true) foto = models.imagefield( upload_to="fotos") resena = models.textfield(null=true, blank=true) invitado = models.booleanfield()
class Charla(models.Model): titulo = models.charfield(max_length=120, unique=true) expositor = models.foreignkey(expositor)
SQL?
SQL? R: Lo genera Django
BEGIN; CREATE TABLE "elinux_noticia" ( "id" serial NOT NULL PRIMARY KEY, "titulo" varchar(80) NOT NULL, "contenido" text NOT NULL ) ; CREATE TABLE "elinux_expositor" ( "id" serial NOT NULL PRIMARY KEY, "nombre" varchar(80) NOT NULL UNIQUE, "foto" varchar(100) NOT NULL, "resena" text NULL ) ; CREATE TABLE "elinux_charla" ( "id" serial NOT NULL PRIMARY KEY, "titulo" varchar(120) NOT NULL UNIQUE, "expositor_id" integer NOT NULL REFERENCES "elinux_expositor" ("id") DEFERRABLE INITIALLY DEFERRED ) ; CREATE INDEX "elinux_charla_expositor_id" ON "elinux_charla" ("expositor_id"); COMMIT;
# Python: class Charla(models.Model): titulo = models.charfield(max_length=120, unique=true) expositor = models.foreignkey(expositor) -- SQL: CREATE TABLE "elinux_charla" ( "id" serial NOT NULL PRIMARY KEY, "titulo" varchar(120) NOT NULL UNIQUE, "expositor_id" integer NOT NULL REFERENCES "elinux_expositor" ("id") DEFERRABLE INITIALLY DEFERRED ); CREATE INDEX "elinux_charla_expositor_id" ON "elinux_charla" ("expositor_id");
Bonus
from django.contrib import admin from elinux.models import Noticia, Expositor, Charla admin.site.register(expositor) admin.site.register(charla) admin.site.register(noticia)
from django.contrib import admin from elinux.models import Noticia, Expositor, Charla class ExpositorAdmin(model.ModelAdmin): search_fields = ('nombre', 'resena') list_filter = ('invitado',) admin.site.register(expositor, ExpositorAdmin) admin.site.register(charla) admin.site.register(noticia)
from django.contrib import admin from elinux.models import Noticia, Expositor, Charla class ExpositorAdmin(model.ModelAdmin): search_fields = ('nombre', 'resena') list_filter = ('invitado',) class CharlaAdmin(model.ModelAdmin): list_display = ('titulo', 'expositor') admin.site.register(expositor, ExpositorAdmin) admin.site.register(charla, CharlaAdmin) admin.site.register(noticia)
Expositor, Charla class ExpositorAdmin(model.ModelAdmin): search_fields = ('nombre', 'resena') list_filter = ('invitado',) class CharlaAdmin(model.ModelAdmin): list_display = ('titulo', 'expositor') class NoticiaAdmin(model.ModelAdmin): date_hierarchy = ('fecha') admin.site.register(expositor, ExpositorAdmin) admin.site.register(charla, CharlaAdmin)
2. Vistas
URLs
urlpatterns = patterns('eldemo.elinux.views', (r'^$', 'index'), (r'^noticias/$', 'noticias'), (r'^noticias/([0-9]+)/$', 'noticia'), (r'^expositores/invitados/$', 'expositores_invitados'), (r'^expositores/seleccionados/$', 'expositores_seleccionados') )
def index(request): noticias = Noticia.objects.all() ultimas_noticias = noticias[:3] return render_to_response( "elinux/index.html", {'noticias': ultimas_noticias})
def noticias(request): noticias = Noticia.objects.all() return render_to_response( "elinux/noticias.html", {'noticias': noticias}) def noticia(request, id_noticia): noticia = Noticia.objects.get( id=id_noticia) return render_to_response( "elinux/noticia.html", {'noticia': noticia})
def expositores_invitados(request): expositores = Expositor.objects.filter( invitado=true) return render_to_response( "elinux/expositores.html", {'expositores': expositores})
3. Templates
Plantilla Base
<body id="page_bg" class="red"> <a name="up" id="up"></a> <div class="center"> <div id="wrapper"> <div id="top"> <div> <div> <span id="logo" style="filter:progid:dximagetransform.microsoft.alphaimageloader(src='http://2008.encuentrolinux.cl/templates/linux2008/images/omt_logo_trans.png',sizingmethod='scale ');"></span> <span id="logo_header" style="filter:progid:dximagetransform.microsoft.alphaimageloader(src='http://2008.encuentrolinux.cl/templates/linux2008/images/omt_logo_header.png',sizingmethod='scal e');"></span> <span id="joomla" style="filter:progid:dximagetransform.microsoft.alphaimageloader(src='http://2008.encuentrolinux.cl/templates/linux2008/images/omt_joomla_trans.png',sizingmethod='sca le');"></span> </div> </div> </div> <div id="middle"> <div id="middle_2"> <div id="middle_3"> <div id="middle_4"> <div id="navigation"> <div id="centernav"> <span id="topnav"> <ul id="mainlevel"> <li class="red_active_menu"> <a href="{% url eldemo.elinux.views.index %}">Inicio</a></li> <ul id="mainlevel"> <li class="red"> <a href="{% url eldemo.elinux.views.noticias %}"> Noticias </a></li> <li class="red"><a href="http://2008.encuentrolinux.cl/index.php? option=com_content&task=view&id=24&itemid=68">inscripciã³n</a></li> <li class="red"><a href="http://2008.encuentrolinux.cl/index.php?option=com_content&task=view&id=13&itemid=28">participan</a></li> <li class="red"><a href="http://2008.encuentrolinux.cl/index.php? option=com_contact&task=view&contact_id=1&itemid=62">contacto</a></li> </ul> </span> <div class="clr"></div> </div> </div> <div id="contentarea"> <table border="0" cellspacing="0" cellpadding="0" width="100%" class="contentarea"> <tr valign="top"> <td id="leftborder"> <div id="pathway"> <span class="pathway"> <a href="http://2008.encuentrolinux.cl/index.php" class="pathway">inicio</a> <img src="http://2008.encuentrolinux.cl/templates/linux2008/images/arrow.png" border="0" alt="arrow" /><!-- TODO: Contacto --> </span> </div> <div id="mainbody"> {% block content %} {% endblock %} </div> </td>
<!-- Lo Importante: -->... <div id="mainbody"> {% block content %}{% endblock %} </div>...
Luego...
<!-- index.html --> {% extends "base.html" %} {% block content %}... {% for noticia in noticias %} <p> <strong>{{ noticia.titulo }}</strong> {{ noticia.contenido truncatewords:6 }} <a href="{% url eldemo.elinux.views.noticia noticia.id %}">(ver más)</a> </p> {% endfor %} {% endblock %}
Bonus: Forms
from django import forms class ContactForm(forms.Form): nombre = forms.charfield(max_length=200) email = forms.emailfield() titulo = forms.charfield(max_length=200) texto = forms.charfield( widget=forms.textarea)
def contacto(request): if request.method == 'POST': form = ContactForm(request.POST) if form.is_valid(): # TODO: Enviar el mail return HttpResponseRedirect('/') else: form = ContactForm() return render_to_response( "elinux/contacto.html", {'form': form})
{% extends "base.html" %} {% block content %} <form action="." method="post"> <table> {{ form.as_table }} </table> <input type="submit" value="enviar" > </form> {% endblock %}
Más Ideas y Posibilidades...
Ubicacion Geográfica de los Asistentes
Comentarios
Ejecución en la JVM (via Jython)
Feeds
Feeds (Oh, pero eso es demasiado fácil)
from django.contrib.syndication.feeds import Feed from elinux.models import Noticia class NoticiasFeed(Feed): title = "Noticias ELinux" link = "/noticias" description = "Noticias Encuentro Linux 2008" def items(self): return Noticia.objects.all()
3. Templates El framework web para perfeccionistas con deadlines
Preguntas?
Gracias! leo.soto@gmail.com http://blog.leosoto.com
Imágenes (Créditos) Desde Flickr (licenciadas vía Creative Commons): http://www.flickr.com/photos nothingpersonal/252531721/ http://www.flickr.com/photos/d_oracle/349073686/ http://www.flickr.com/photos/d_oracle/350780566/ http://www.flickr.com/photos/spine/2425394931/ http://www.flickr.com/photos/nino63004/2471663305/ http://www.flickr.com/photos/ryanricketts/2295726918/ http://www.flickr.com/photos/twatson/2854156629/ http://www.flickr.com/photos/funkybug/1538454520/ http://www.flickr.com/photos/nirak/331916210/