>>> from datetime import date
>>> current_date=date.today()
>>> carry, new_month=divmod(current_date.month-1+1, 12)
>>> new_month+=1
>>> current_date=current_date.replace(year=current_date.year+carry, month=new_month)
>>> print date.today()
2011-05-21
>>> print current_date
2011-06-21
>>>
sábado, 21 de mayo de 2011
Sumar un mes con python
lunes, 4 de abril de 2011
Ubuntu One trabaja con IIS!!!
Anda que... estaba yo sicronizando música con Ubuntu One, me da un error de red y me sale:
HTTP Error 404 - File or directory not found.
The page cannot be found
The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.Please try the following:
- Make sure that the Web site address displayed in the address bar of your browser is spelled and formatted correctly.
- If you reached this page by clicking a link, contact the Web site administrator to alert them that the link is incorrectly formatted.
- Click the Back button to try another link.
HTTP Error 404 - File or directory not found.
Internet Information Services (IIS)
Technical Information (for support personnel)
- Go to Microsoft Product Support Services and perform a title search for the words HTTP and 404.
- Open IIS Help, which is accessible in IIS Manager (inetmgr), and search for topics titled Web Site Setup, Common Administrative Tasks, andAbout Custom Error Messages.
UArrrrrrgggg!!
viernes, 11 de marzo de 2011
Django: Evitar error en el administrador "decoding Unicode is not supported"
Si, como es probable, os habéis encontrado con este error en el administrador cuando examináis modelos con caracteres utf-8, creo que puede deberse al hecho de que django sirve los strings en unicode pero sin codificar.
En python, en el momento que intentamos algo como esto:
Obtenemos el TypeError. En el admin de django, el error lo obtendremos siempre que grabemos caracteres >255. Parece provenir del hecho de codificar el unicode en ascii en vez de utf-8 ¿?.
Si hacemos:
Obtendremos el error de decodificación ascii, pero si hacemos...
...nos funcionará pero no podremos usar el admin para examinar el modelo porque nos genera el error anterior.
Tenemos dos posibilidades, aunque no las comprendo en profundidad:
Solución 1):
En los modelos poner:
Solución 2) Llamado "método del literal"
En todo caso es conveniente poner el setting
que fuerza utf-8 a la hora de procesar y servir las plantillas.
Más info sobre este tema estaría bien. En mi caso uso mysql con utf-8 y ordenación spanish2, ubuntu 10.10 con utf-8 y apache forzado a servir utf-8.
En python, en el momento que intentamos algo como esto:
>>> unicode('pepe', 'utf-8')
u'pepe'
>>> unicode(u'pepe', 'utf-8')
Traceback (most recent call last):
File "", line 1, in
TypeError: decoding Unicode is not supported
Obtenemos el TypeError. En el admin de django, el error lo obtendremos siempre que grabemos caracteres >255. Parece provenir del hecho de codificar el unicode en ascii en vez de utf-8 ¿?.
Si hacemos:
def __unicode__(self):
return unicode(self.descripcion)
Obtendremos el error de decodificación ascii, pero si hacemos...
def __unicode__(self):
return unicode(self.descripcion, 'utf-8')
...nos funcionará pero no podremos usar el admin para examinar el modelo porque nos genera el error anterior.
Tenemos dos posibilidades, aunque no las comprendo en profundidad:
Solución 1):
from django.utils.encoding import smart_unicode
En los modelos poner:
def __unicode__(self):
return smart_unicode(("%s" % self.descripcion))
Solución 2) Llamado "método del literal"
def __unicode__(self):
return (u"%s" % self.descripcion)
En todo caso es conveniente poner el setting
DEFAULT_CHARSET='utf-8'
que fuerza utf-8 a la hora de procesar y servir las plantillas.
Más info sobre este tema estaría bien. En mi caso uso mysql con utf-8 y ordenación spanish2, ubuntu 10.10 con utf-8 y apache forzado a servir utf-8.
jueves, 10 de marzo de 2011
Django: Guardar imágenes (o blobs) desde la red
Debido a las consultas amplío el post anterior para aclarar un poco el proceso suponiendo que bajamos las imágenes desde un servidor sFTP, sólo hay que cambiar los parámetros de pycurl para operar con http, https, etc...
Primero bajamos la imagen a memoria con algún gestor (pycurl por ejemplo o urllib) y guardarlo en un cStringIO:
Ahora ya tenemos la imagen en memoria (buf), vamos a grabarla (django la graba en disco y en la db solo se guarda el path), el único problema es que ImageField espera un campo file, pero lo solucionaremos con un workaround:
En tu modelo pones:
Donde settings.PATH_FOTOS_CLIENTES apunta a la ruta que cuelga de la ruta que tengas en settings.MEDIA_ROOT y tiene el formato siguiente o similar (en settings.py):
Ahora tenemos que pasar de la imagen que tienes cargada en memoria a un stream tipo 'file' para que pueda ser guardado por el modelo:
y ya salvamos:
Comentad si os surge alguna duda.
Saludos,
Pere Vilás.
Primero bajamos la imagen a memoria con algún gestor (pycurl por ejemplo o urllib) y guardarlo en un cStringIO:
import pycurl, cStringIO
buf = cStringIO.StringIO()
url=('ftps://%s:990/%s' % (ip, fichero))
privatekey = '/home/sss/.ssh/id_rsa'
options = {
pycurl.USERPWD: 'xxxxx:xxxx',
pycurl.SSLKEYPASSWD: 'adfasdfasdfas',
pycurl.SSH_PRIVATE_KEYFILE: privatekey,
pycurl.SSH_PUBLIC_KEYFILE: privatekey + '.pub',
#pycurl.WRITEDATA: open('/dev/null', 'wb'),
pycurl.VERBOSE: 1,
pycurl.URL: url,
pycurl.HEADER: 1,
pycurl.NOBODY: 1,
pycurl.WRITEFUNCTION: buf.write,
pycurl.NOPROGRESS: 1,
pycurl.SSL_VERIFYPEER: 0,
pycurl.SSL_VERIFYHOST: 0,
}
gestor = pycurl.Curl()
try:
for (k, v) in options.items():
print k, v
gestor.setopt(k, v)
except Exception, msg:
logging.info('Error setopt %s' % msg)
gestor.perform()
Ahora ya tenemos la imagen en memoria (buf), vamos a grabarla (django la graba en disco y en la db solo se guarda el path), el único problema es que ImageField espera un campo file, pero lo solucionaremos con un workaround:
En tu modelo pones:
class Persona(models.Model):
.....
imagen=models.ImageField(upload_to=settings.PATH_FOTOS_CLIENTES, blank=True)
Donde settings.PATH_FOTOS_CLIENTES apunta a la ruta que cuelga de la ruta que tengas en settings.MEDIA_ROOT y tiene el formato siguiente o similar (en settings.py):
PATH_FOTOS_CLIENTES='clientes/%Y/%m/%d'
Ahora tenemos que pasar de la imagen que tienes cargada en memoria a un stream tipo 'file' para que pueda ser guardado por el modelo:
from django.core.files.uploadedfile import SimpleUploadedFile
foto = SimpleUploadedFile('imagencliente.jpg',
buf.getvalue(),
"image/jpeg")
y ya salvamos:
p=Persona( imagen=foto )
p.save()
Comentad si os surge alguna duda.
Saludos,
Pere Vilás.
miércoles, 9 de marzo de 2011
Django: Guardar imágenes desde string
Para guardar una imagen en un campo de tipo ImageField de Model desde una cadena como un POST http o desde memoria hacemos lo siguiente:
Espero que os sirva ;-)
from django.core.files.uploadedfile import SimpleUploadedFile
import cStringIO
buf = cStringIO.StringIO()
# adquirimos imagen y la guardamos en buf i.e. mediante pycurl
foto = SimpleUploadedFile('imagen.jpg', buf.getvalue(), "image/jpeg")
# ahora foto contiene el stream pero en formato 'fichero'
p=Modelo( imagen=foto )
p.save()
Espero que os sirva ;-)
Django en la red con el servidor de desarrollo
No basta con python manage.py runserver [num_puerto], esto sólo lo hace accesible desde loopback, para servir en red hay que hacer
Para saber nuestra ip podemos hacerlo con ifconfig, evidentemente no podemos usar localhost o 127.0.0.1
python manage.py runserver [ip_fisica]:[num_puerto]
Para saber nuestra ip podemos hacerlo con ifconfig, evidentemente no podemos usar localhost o 127.0.0.1
jueves, 24 de febrero de 2011
Consultas en Django
Unos pequeños apuntes cogidos al vuelo de consultas en django
Un queryset sería el equivalente a un SELECT
Un filter sería el equivalente a un WHERE
Comandos de Query:
Objeto.objects.all() -> Todo el conjunto
Objeto.objects.filter() -> Un filtro para incluir
Objeto.objects.exclude() -> Un filtro para excluir
Objeto.objects.get() -> Busca un solo objeto
Encadenado de filtros
Entry.objects.filter(headline__startswith=’What’
).exclude(
pub_date__gte=datetime.now()
).filter(
pub_date__gte=datetime(2005,1,1)
)
Todos los que empiezan por What entre 1/1/2005 y ahora.
Cada filtro crea una consulta única
q1=Entry.objects.filter(headline__startswith=’What’)q2=q1.exclude(pub_date__gte=datetime.now())
q3=q2.filter(pub_date__gte=datetime(2005,1,1))
Buscar un solo objeto con get()
one_entry=Entry.objects.get(pk=1)Si no hay datos salta la excepción DoesNotExist
from django.core.exceptions import ObjectdoesNotExist
try:
one_entry=Entry.object.get(pk=numero)
except ObjectDoesNotExist, e:
mensaje=("La entrada %n no existe" % (numero))
En cambio filter()[0], no hace saltar ninguna excepción.
Limitar el número de registros devueltos
Entry.objects.all()[:5] # los cinco primerosEntry.objects.all()[5:10] # del quinto al décimo
Buscar sobre campos
Básicos: Son de la forma campo__tipobusqueda=valorEjemplo: Entry.objects.filter(pub_date___lte=’2006-01-01’) se transforma en select from blog_entry where pub_date<=’2006-01-01’
-> exact : headline__exact=’algo’
-> iexact: case insentive exact
-> contains
-> startswith
-> endswith
Relacionales
Entry.objects.filter(blog__name__exact=’Pep’)Blogs.objects.filter(entry__headline__contains=’Pep’, entry__pub_date__year=2006)
Todos los blogs que tengan alguna entrada cuyo titulo tenga Pep y se haya publicado en 2006
Blogs.objects.filter(entry__headline__contains=’Pep’).filter(entry__pub_date__year=2006)
Todos los que tengan Pep y todos los que se hayan publicado en 2006
Filtros que referencian a otros campos del mismo modelo
from django.db.models import FEntry.objects.filter(n_coments__gt=F(‘n_pingbacks’))
gt: greather than
n_pingbacks: valor de otro campo del mismo modelo
Primary key
Blog.objects.get(pk=valor).get(pk__in=[1,4,7])
.get(pk__gt=14)
Caching
Esta consulta se realiza dos veces:print [e.headline from p in queryset]
print [e.pub_date from p in queryset]
Esta, sólo una vez (cacheo de resultados):
queryset=Entry.objects.all()
print [p.headline form p in queryset] <- En esta se cachea
print [p.pub_date form p in queryset] <- en esta su usa la caché
Consultas complejas con Q
Las palabras clave en filter, etc... son ANDs, si queremos algo más complejo, necesitamos Qsdjango.db.models.Q
Q(question__startswith=’Who’) | Q(question__startswith=’What’)
Q(question__startswith=’Who’) | ~Q(question__startswith=’What’)
Poll.objects.get( Q(question__startswith=’Who’),
Q(pub_date=date(2005,5,2)) | Q(pub_date=date(2005,5,6)) )
Comparando objetos
Para comparar dos objetos usamos el == estándar de pythonuna_entrada==otra_entrada
La comparación se realiza siempre usando la clave primaria
Borrando objetos
Entry.objects.filter(pub_date__year=2005).delete()Borra todos los elementos y los foreign key que le apuntan en cascada
b=Blogs.objects.get(pk=1)
b.delete() -> borra la entrada y todos sus comentarios
Update de varios elementos
Entry.objects.filter().update(headline=’Cambiado’)Objetos relacionados
Si un modelo tiene un foreign key, podemos acceder al objeto foráneo via simple atributo del modelo:e=Blog.objects.get(id=1)
e.entry_set.all() --> todas las entradas del primer blog
e.entry_set.filter(headline__contains=’Pep’)
Si se ha usado el related_name en la definición del modelo, entonces ese es el nombre del atributo para acceder
blog=ForeignKey(Blog, related_name=’entries’)
b=Blog.objects.get(id=1)
b.entries.all()
b.entries.count()
Métodos del Foreign Manager:
relacionado.add(ob1, obj2, …) Añade al objeto relacionado
relacionado.create(**kwargs)
relacionado.remove(obj1, obj2, …)
relacionado.clear() -> borra todos los objetos relacionados
O también:
b=Blog.objects.get(id=1)
b.entry_set=[e1, e2, …] <- un objeto iterable
Hacer siempre el save del objeto principal para que permanente.
Suscribirse a:
Entradas (Atom)