viernes, 28 de marzo de 2008

Error 404 y 505 diferentes para cada aplicación dentro de un mismo proyecto Django

Django por defecto usa una template error 404 y error 500 por proyecto.
Pero... ¿qué pasa si uno quiere usar diferentes páginas de error 404 y 500 para distintas aplicaciones dentro de un mismo proyecto?
Después de estar tratando de crear mi propio handler 404, y darme cuenta que no podía usar uno distinto por aplicación (Los handler 404 y 500 siguen siendo los mismos para el proyecto), me di cuenta que podía usar dos settings.py y usar las directivas de configuración de apache para usar uno u otro, dependiendo de la URL a la que se acceda.
Entonces, en el httpd.conf (o en alguna extensión que se coloque en el dir httpd/conf.d/):

SetHandler python-program
PythonHandler django.core.handlers.modpython
PythonPath "['/home/userx/djangoapps'] + sys.path"
SetEnv DJANGO_SETTINGS_MODULE proyect.settings
PythonDebug On


SetHandler python-program
PythonHandler django.core.handlers.modpython
PythonPath "['/home/userx/djangoapps'] + sys.path"
SetEnv DJANGO_SETTINGS_MODULE proyect.settings_app2
PythonDebug On

Luego tengo dos settings, en el nuevo (app2) dejo mi aplicación antes que las demás para que ubique las templates 404 y 500 desde ahí.

INSTALLED_APPS = (
...
'proyect.app2',
'proyect.app1',
...,
)


y pongo debug=False y chan, chan! tengo un sólo proyecto con dos aplicaciones que direccionan a distintas páginas de error 404 y 500.
Muy chanchullesco? Bueno... por lo menos resulta.

lunes, 24 de marzo de 2008

Malditas fechas!

Siempre me ha complicado el manejo de fechas en cualquier lenguaje, aquí algunos tips de fechas en python:

>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2008, 3, 24, 14, 3, 2, 704594)
>>> "%s" % datetime.datetime.now()
'2008-03-24 14:03:15.171016'

Lo mismo pero sin decimales
>>> "%s" % datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
'2008-03-24 14:05:19'

Y acerca de diferencia entre fechas
>>> d1=datetime.datetime.now()
>>> d2=datetime.datetime.now()
>>> ddiff=d2-d1
>>> ddiff
datetime.timedelta(0, 15, 565414)
>>> str(ddiff)
'0:16:12.826069'

Lo mismo pero sin decimales
>>> str(ddiff)[:len(dstr)-7]
'0:16:12'

Ya lo sé, ya lo sé, no es muy bonito, la otra opción más correcta sería:
>>> h=ddiff.seconds/3600
>>> m=ddiff.seconds/60-h*60
>>> s=ddiff.seconds-h*60-m*60
>>> "%i:%i:%i" % (h,m,s)
'0:16:12'


Obviamente, siempre se puede ver la documentación oficial:
http://docs.python.org/lib/module-datetime.html

martes, 18 de marzo de 2008

Cómo obtener dirección IP en Django

Fácil, usar el objeto request: request.META['REMOTE_ADDR']

Después de cabecearme un rato, vi que la documentación lo decía:
http://www.djangoproject.com/documentation/request_response/#attributes

Hice una prueba para ver cómo se veía request.META y esto fue lo que obtuve:
[AUTH_TYPE]: None
[HTTP_COOKIE]: sessionid=4993370cb1d7b51eb013a6f12eccacc4; __utma=258392522.165289698.1205853464.1205853464.1205853464.1; __utmz=258392522.1205853464.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmb=258392522.1; __utmc=258392522.1
[SERVER_SOFTWARE]: mod_python
[SCRIPT_NAME]: None
[REQUEST_METHOD]: GET
[PATH_INFO]: /test/
[SERVER_PROTOCOL]: HTTP/1.1
[QUERY_STRING]: None
[HTTP_TE]: deflate, gzip, chunked, identity, trailers
[CONTENT_LENGTH]: 0
[HTTP_ACCEPT_CHARSET]: iso-8859-1, utf-8, utf-16, *;q=0.1
[REMOTE_USER]: None
[HTTP_CONNECTION]: Keep-Alive, TE
[SERVER_NAME]: kultrun.intra.wiseocean.cl
[REMOTE_ADDR]: 192.168.10.68
[PATH_TRANSLATED]: None
[SERVER_PORT]: 0
[HTTP_USER_AGENT]: Opera/9.26 (X11; Linux i686; U; en)
[HTTP_HOST]: 192.168.10.68
[HTTP_COOKIE2]: $Version=1
[HTTP_CACHE_CONTROL]: no-cache
[HTTP_ACCEPT]: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
[GATEWAY_INTERFACE]: CGI/1.1
[HTTP_ACCEPT_LANGUAGE]: en-US,en;q=0.9
[REMOTE_IDENT]: None
[CONTENT_TYPE]: None
[REMOTE_HOST]: None
[HTTP_ACCEPT_ENCODING]: deflate, gzip, x-gzip, identity, *;q=0


En caso de necesitar la IP directamente desde python sin pasar por django, se puede hacer:

import socket
socket.gethostbyname(socket.gethostname())
socket.gethostbyname_ex(socket.gethostname())

lunes, 17 de marzo de 2008

Buenos Links para tener a mano

Django
Página Oficial: http://www.djangoproject.com/
Documentación oficial: http://www.djangoproject.com/documentation/
Django Book: http://www.djangobook.com/
Comunidad de usuarios Django en el mundo: http://djangopeople.net/
Django Snippets: http://www.djangosnippets.org/
B-List, aquí siempre hay varios artículos Django: http://www.b-list.org/
Blog de Marcelo Ramos, en el blog de este loco he visto cosas interesantes.
Igor Weblog, otro blog con cosas Django

Python
Página oficial: http://www.python.org/
Una muy buena referencia rápida: Python 2.4 Quick Reference
Manejo fechas en Python: http://pleac.sourceforge.net/pleac_python/datesandtimes.html

 

jueves, 13 de marzo de 2008

¿Sabías que en python bool('False')=True ?

Bueno, yo no lo sabía y me costó un rato encontrar un error asociado a eso.
En realidad es un asunto lógico un string vacío es False y uno lleno True.

Interesante el juego de palabras, ¿no?

viernes, 7 de marzo de 2008

Cómo crear un Blog en Django 0.96 y no morir en el intento


Después de una ardua tarea buscando y probando Blogs tipos add-on para Django 0.96, me pareció pertinente compartir, a ver si a alguien le sirve, y si a nadie le sirve, por último para no olvidarme de lo que hice...

Primero Googleando, encontré y probé estos blogs:
http://code.google.com/p/django-diario/
http://code.google.com/p/django-basic-blog/
http://code.google.com/p/coltrane-blog/

Eran para la versión de desarrollo de Django, e inicialmente yo creía inocentemente que iba a poder hacer los suficientes hacks para que anduvieran en Django 0.96 y que no iban a ser muchos.... mala idea.... después de un par de días, me di por vencido... hay muchas cosas en las urls y en varias otras librerías que se han mejorado.

Después, encontré una buena información en este sitio:
http://paltman.com/2008/02/02/i-want-to-move-my-blog-to-django/

Finalmente instalé y empecé a probar este:
http://code.google.com/p/blogmaker/
Que fue el único (de la lista anterior y otras) que encontré para Django 0.96. Pero tuve el problema que es para Python 2.5 ... y yo tengo Python 2.4!!!!!!!
Inconveniente: Me era muy costozo cambiar de 2.4 a 2.5 (además mi jefe dijo: que sea la última opción... ni modo)
Solución: Vi que de Python 2.5 sólo se usaba la librería hashlib, y más específicamente md5, entonces reemplacé hashlib.md5 por md5.md5().hexdigest()

Otra cosa fue que por defecto Django 0.96 trae los siguientes TEMPLATE_CONTEXT_PROCESSORS
("django.core.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n")
Y BlogMaker usa además otro:
django.core.context_processors.i18n
Para agregarlo, hay que modificar el settings.py del proyecto y agregarle esto:
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.request",
)


Después me faltaba una librería: Python-Markdown
La bajé de aquí: http://www.freewisdom.org/projects/python-markdown/
E instalarla fue muy fácil:
$ unzip python_markdown-1.7.rc1.zip
$ cd python_markdown-1.7

$ sudo python setup.py install

Después tuve que cambiar la url (que está hardcoded) a la que salta la plantilla para dejar comentarios:
$ vi blogmaker/comments/templates/comments/comment_form.html

Eso fue todo y la cosa empezó a andar picho caluga.... ahora que mi amigo que está editando las plantillas para darle nuestro formato me esté diciéndo que están medio juleras, es otra cosa.... vamos a ver cómo evoluciona nuestra experiencia con BlogMaker para Django.

Bueno, y si alguien sabe cómo hacer esto que hice de una manera más fácil... SUELTA LA PEPA!!! y di como se hace! ... por lo menos una persona (yo), estará muy agradecido ;-

Django & Python Tips

Un lugar para reunir información, tips, noticias, paltas acerca de Django (El Web framework para perfeccionistas) y Python (El lenguaje interactivo, expresivo y legible, que a muchos nos ha hecho fanáticos de él).

Estoy haciendo esto como medio para guardar las típicas paltas que sino se escriben después cuesta acordarse, los links que se ven bacanes y que después dije "DONDE #$@&! LO ANOTÉ!!!", las noticias que no quiero olvidar y en fin, todo lo compartible que vea por ahí del mundo Django y Python.

... Y en español (por ahora)