martes, 27 de diciembre de 2011
¿Un paseito por la Luna?
Para celebrar fin de año, os propongo este bonito vídeo que he subido a youtube. En él podremos disfrutar un paseo por la superficie lunar con el Lunar Roving Vehicle. A partir del minuto 0:52 la cámara está filmando encima del rover.
El Apolo 16 fué el penúltimo en alunizar y el primero en hacerlo en una zona montañosa. Se lanzo desde Cabo Cañaveral el 16 de Abril de 1972. En total, la misión duró once días de los cuales tres pasaron sobre la superficie de la Luna. El Comandante John Young y el Piloto Charles Duke son los protagonistas del vídeo.
Molts d'anys i bons! Bon 2012!
miércoles, 21 de diciembre de 2011
Ibiza Eivissa en google street view
lunes, 5 de diciembre de 2011
Shell en django
shell.sh
export DJANGO_SETTINGS_MODULE="settings"
python
desde aquí ya podemos operar con los modelos:
from gesion.models import Cliente
c=Cliente(clave='444', descripcion='Pepe Perez')
c.save()
Si queremos acceder desde un script independiente en python podemos usar setup_environ de esta forma:
mantenimiento.py
from django.core.management import setup_environ
try:
import settings
except ImportError:
import sys
sys.stderr.write("No encuentro el fichero de settings")
sys.exit(1)
setup_environ(settings)
....
Espero que os sirva.
jueves, 24 de noviembre de 2011
Copiar pdf a iPhone iPad fácil ubuntu
miércoles, 23 de noviembre de 2011
Tiempo EST, CET, CEST, PST
Vale. ¿Y eso qué hora es en España?. El tiempo EST se refiere al tiempo oficial de la costa este de los EEUU. En España peninsular e Illes Balears estamos en el tiempo CET (Central European Time) o CEST en verano (Central European Sumer Time), es decir en GMT+1 o GMT+2 en verano, GMT corresponde a la hora en el meridiano 0 o meridiano de Greenwich .
Si miramos este mapa de husos horarios de wikipedia vemos que Cabo Cañaveral está en la costa este, en el uso GMT-5 (en amarillo). En invierno, como España está en el huso GMT+1 (en verde) tenemos que sumar 6 horas al tiempo EST para que nos dé en tiempo CET. O sea, el Curiosity será lanzado a las 16:02 h, tiempo de España y les Illes Balears, una hora menos en las Islas Canarias.
El tiempo EST es importante por ser el usado por los grandes núcleos de población de los EEUU (Boston, Whashington, Nueva York y Miami). Otra zona horaria importante es la usada en la costa oeste, el llamado PST (Pacific Standard Time) por ser el usado en Seattle, Portland, San Francisco y Los Ángeles. En este caso el huso está en GMT-08 y por lo tanto hay que sumar 8 horas para transformarlo en GMT y de ahí una hora más para pasarlo a EST. En total hay una diferencia horaria de nueve horas.
Observamos que para calcular la hora equivalente en otro huso que está más al Oeste (ir hacia la izquierda) tenemos que restar los husos que vamos pasando. Para calcular la hora equivalente a otro huso que está más al Este (ir hacia la derecha) tenemos que sumar los husos que vamos pasando. De todas formas, hay que consultar el mapa porque como veis, la hora oficial depende de consideraciones políticas p.e. Groenlandia cae en cinco zonas horarias pero sólo usa tres.
La mayoría de países europeos usan CET (en verde) menos Portugal, Irlanda y Reino Unido a la izquierda en los que hay que restar una hora.
viernes, 18 de noviembre de 2011
Encapsulado del Mars Science Laboratoy (MSL) "Curiosity"
El MSL preparado para su encapsulamiento en la cofia. Imagen NASA/KSC |
La maniobra de entrada, descenso y aterrizaje (EDL - Entry, descending and landing) es una de las más peligrosas de la misión y no han sido pocas las naves que se han perdido durante esta fase. En esta animación con música de película, se pueden seguir toda la secuencia de este original y complejo método.
Más vídeos del MSL en la web de la NASA.
Cargan el Mars Science Laboratoy (MSL) "Curiosity" con el generador de radioisótopos
Fuente de alimentación del MSL. Imagen NASA/KSC |
martes, 15 de noviembre de 2011
ebooks de EdicionesB. Así si.
Como bien argumentan los promotores, lo primero es que la gente lea y después seguro que acaban comprando los originales siempre que el precio no sea abusivo.
Fuente: el país.
jueves, 10 de noviembre de 2011
Estado de la Phobos-Grunt
La estación de la ESA en Australia ha sido incapaz de comunicarse con la sonda aunque esta ha pasado directamente en su linea de visión. Se cree que que la nave está rotando y sólo en el caso de que una de las antenas de baja ganancia apunte en ese momento a la Tierra va a ser posible la comunicación. La única buena noticia es que la órbita se ha estabilizado lo cuál puede significar que todos los sistemas (menos las comunicaciones) están funcionando.
24/11/2011
¡¡¡La sonda está viva!!! La antena de la ESA en Australia han conseguido la portadora en el primer paso y la telemetría completa en el segundo después de instalar un dispositivo específico para contactar con la phobos-grunt. Ahora se trata de ver si puede reprogramarse el ordenador de abordo y decidir cómo se modifica la misión toda vez que la ventana para la misión completa se ha cerrado.
16/11/2011
Seguimos a la espera de un comunicado oficial pero, según parece, después del lanzamiento de la soyuz TMA-22 el jefe de Roskosmos, Vladimir Popovki, tuvo que enfrentarse a los periodistas que le increparon acerca de la política informativa de su agencia en relación a la phobos-grunt.
Según Popovki, intentarán conectar con la sonda mientras exista ventana de lanzamiento (hasta mediados de diciembre). Relató que en ningún momento han conseguido telemetría de la nave. De lograrlo, al menos nos permitiría saber qué ha ocurrido exactamente para llegar a esta catastrófica situación.
El ordenador de abordo está programado para establecer contacto una vez se ha efectuado el primer disparo. Como este nunca se ha producido parece que es prácticamente imposible recuperar el control del artefacto.
Respecto a la reentrada, afirmó que según sus cálculos el combustible tóxico no debería llegar a tierra ya que haría explosión en la alta atmósfera. Esta opinión no es compartida por otros especialistas.
Russianspaceweb informa de que el contacto con la sonda es muy complicado ya que la baja altura de la sonda hace que apenas entre en la cobertura de las antenas por unos segundos. Estas antenas gigantes fueron diseñadas para misiones de espacio profundo. En estas condiciones es muy difícil retomar en control de la nave. El seguimiento óptico para refinar la órbita tampoco está funcionando ya que son sistemas militares diseñados para seguimientos en órbita geoestacionaria, mucho más elevada que la actual. El personal de la ISS intentó fotografiar la sonda infructuosamente, aunque por la curva de luz parece que tiene los paneles desplegados y está correctamente orientada.
Fuentes:
russianspaceweb.com
spaceflightnow.com
11/11/2001
spaceflight.now no aporta nada nuevo hoy. El diario elpais informa de que prácticamente dan la sonda por perdida y ya especula con el lugar donde chocará y que lleva hidracina en sus tanques. http://www.russianspaceweb.com informa de que la nave ha sido diseñada para que todas las operaciones en esta fase sean automáticas y por lo tanto, toda solución debería ser totalmente improvisada.
10/11/2011
Resumen de la misión phobos-grunt |
Llama la atención el gran despliegue mediático anterior al lanzamiento y el silencio que se ha hecho desde que empezaron los problemas.
Detalle de la ruta de escape de la phobos-grunt |
09/11/2011
Como sabéis, la phobos-grunt no ha sido capaz de encender sus motores una vez en órbita. Los controladores disponen de tres días antes de que se agoten las baterías que gestionan el ordenador que controla el disparo de los propulsores para dar a la nave velocidad de escape e insertarla en una órbita hacia Marte. La carga de propelentes está intacta pero la nave ha sido incapaz de orientarse y por ello ha entrado en modo seguro. Un aficionado al seguimiento óptico de satélites grabó desde Sao Paulo la inserción en órbita
Fuentes:
http://www.russianspaceweb.com/phobos_grunt_launch.html#11_10
http://www.planetary.org/blog/article/00003252/
http://translate.google.com/translate?hl=es&sl=ru&tl=es&u=http%3A%2F%2Fwww.federalspace.ru%2Fmain.php%3Fid%3D2%26nid%3D18227
Imágenes:
Roskosmos
jueves, 3 de noviembre de 2011
Format a pdf file for Kindle or Kindle DX
If you don't have any pdf printer installed because you use windows I recommend the CutePDF.
Formatear pdf para Kindle o Kindle DX
Si no tenéis ninguna impresora pdf instalada por que usáis windows os recomiendo el cutepdf.
miércoles, 2 de noviembre de 2011
Cita de Poincaré
Jules Henri Poincaré
sábado, 29 de octubre de 2011
Copia de seguridad en pdf o mobi de archivos con DRM de Adobe
- Adobe Digital Editions no tiene versión para Linux, lo cuál me parece una falta de respeto a los usuarios de este sistema operativo libre.
- El renderizado del documento lo hace el propio digital editions siendo la calidad de visualización inferior al de cualquier visor de pdf.
- No podéis leer el documento en vuestro lector de ebooks o tableta.
A mí personalmente me parece una tomadura de pelo, por que para eso es mejor comprarse la versión en papel. Por lo tanto, he decidido compartir este link con vosotros para que podáis realizar una copia de seguridad privada en un formato con el contenido en claro. Tened en cuenta que compartir este fichero en claro puede ser ilegal y debe usarse sólo para mejorar el visionado o leer el texto en la tableta.
Método
Su método hace uso de dos scripts en python:
- Uno de ellos rompe la ofuscación de la clave única de usuario y la graba al disco duro (es conveniente guardarla).
- El otro descrifa el texto usando esa clave.
Sólo tenéis que pasar el fichero con DRM a linux y ejecutar los dos scripts. Para los usuarios de windows hay instruciones adicionales :
- Bajar e instalar Python 2.6 y PyCrypto.
- Bajar los dos scripts anteriores y guardarlos en un directorio con los nombres intepkey.pyw e ineptpub.pyw.
- Guardar el libro a descifrar en el mismo directorio y ejecutar inetkey.pyw y luego ineptepub.pyw sobre el libro.
miércoles, 26 de octubre de 2011
Archivo histórico de la Royal Society de acceso libre
http://royalsocietypublishing.org/
lunes, 24 de octubre de 2011
La Coalición de la Voluntad
La Coalición de la Voluntad from Horatiux on Vimeo.
jueves, 20 de octubre de 2011
Retrasado primer lanzamiento Soyuz desde Guayana
miércoles, 19 de octubre de 2011
Cadenas de Markov y filosofía de vida
"El anterior ejemplo es una Cadena de Markov (ver definición 122), cuya principal característica es que, aunque el futuro depende del pasado, el futuro resulta condicionalmente independiente del pasado cuando se conoce el presente. Esta propiedad me parece un principio importante para aplicar a una vida positiva: Todo mi futuro depende solamente de quién soy yo en este momento, independientemente de cómo llegué a ser lo que soy. Mi futuro sólo dependerá de mi pasado si yo no sé quién soy en este momento."
lunes, 17 de octubre de 2011
Poster de la Phobos-Grunt
Ideal para colgar en la pared de la habitación.
Imágen: Roskosmos (Russian Federal Space Agency)/IKI
La actitud es tan importante o más que el currículo
"El trabajo en equipo, la flexibilidad, la movilidad y el espíritu emprendedor son algunos de los aspectos que más valora una empresa a la hora de contratar a un trabajador"
Les millors preguntes:
–En estos momentos de recesión, ¿qué perfiles son los más demandados por las empresas?
–Administrativos, comerciales y vendedores siguen estando al a cabeza de la demanda. Después informáticos, ingenieros y profesionales del sector salud.
–¿Qué formación complementaria o competencias son las más valoradas entre las empresas que ofertan puestos de trabajo?
–Idiomas sin duda es la más valorada, en muchísimas ofertas se solicita el dominio de Inglés , Alemán y Francés.
–Por último, ¿qué tres consejos podría dar a toda persona que está buscando empleo en estos momentos y no encuentra salida?
–Que no desespere, que aproveche a formarse lo mejor posible, haciendo cursos, máster, postgrados, y sobre todo, estudiando idiomas hasta conseguir un nivel muy alto, que es una diferencia competitiva tremenda, y que utilice Internet como herramienta para buscar empleo y generar contactos.
viernes, 7 de octubre de 2011
Uso correcto de super en python
class Base(object):
def __init__(self):
print "Base created"
class ChildA(Base):
def __init__(self):
Base.__init__(self)
class ChildB(Base):
def __init__(self):
super(ChildB, self).__init__()
¿Qué diferencia hay entre la construcción de A y de B?. Pues ninguna, lo que ocurre es que super (versión B) nos permite mayor flexibilidad para gestionar la jerarquía ya que no tenemos que referirnos a una clase en particular.Usar super es también la única forma de hacer herencia múltiple aunque yo no la uso por ser fuente de errores.
En python 3, la sintaxis se simplifica de super(ChildB,self).__init__() a super().__init().
Fuentes:
Understanding Python super() and init methods
http://stackoverflow.com/questions/576169/understanding-python-super-and-init-methods
How to use 'super' in python
http://stackoverflow.com/questions/222877/how-to-use-super-in-python
miércoles, 21 de septiembre de 2011
Biblioteca de ebooks técnico-científicos
martes, 20 de septiembre de 2011
Download a youtube playlist
- Download the latest version of youtube-dl. It's a python script that you can save in your donws directory as youtube-dl.py or do a chmod +x and save in /usr/bin
- Create a new playlist o access to a ready one. Notice that the url is something similar to http://www.youtube.com/playlist?list=PL444659F515B8CC1B
- In your download directory run the python script python youtubel-dl.py --max-quality mp4 -t http://www.youtube.com/playlist?list=PL444659F515B8CC1B
That's all!
Bajar lista de reproducción de youtube
- Bajarte la última versión de youtube-dl es un script python que puedes guardar en el directorio de descargas como youtube-dl.py o hacerlo ejecutable y grabarlo en /usr/bin
- Te creas una lista de reproducción o accedes a una ya creada y verás que la url es algo similar a http://www.youtube.com/playlist?list=PL444659F515B8CC1B
- En el directorio de Descargas hacer python youtube-dl.py --max-quality mp4 -t http://www.youtube.com/playlist?list=PL444659F515B8CC1B
That's all!
viernes, 9 de septiembre de 2011
Campos de un modelo en Django
>>> from django.db import models
>>> from personal.models import Seccion
>>> campos=Seccion._meta.fields
>>> print campos
django.db.models.fields.AutoField object at 0x96a33ac, ...
>>> for a in campos:
... print a.name
...
id
convenio
descripcion
hora_corte
>>>
Toda la información del modelo está en el _meta. Un modelo puede cargarse dinámicamente con:
model = models.get_model('aplicacion', 'Modelo')
Todas las opciones están bien documentadas en el fuente django/db/models/options.py
miércoles, 7 de septiembre de 2011
Alternativa 3
Alternativa 3, vista en "Las puertas del misterio" de Jiménez del Oso es un documental de 1977 en el que salen muchas imágenes de científicos e instalaciones como laboratorios y radiotelescopios de la época. Aunque la calidad es muy mala os recomiendo que lo veáis hasta el final porque os aseguro que no tiene desperdicio.
Vídeo de youtube
martes, 6 de septiembre de 2011
Bookmarks rápidos en chrome
1.- Ctrl+Shift+B para sacar la barra de marcadores
2.- Arrastramos cualquier página desde la barra de navegación a la barra de marcadores.
3.- click derecho sobre el marcador -> Editar
4.- Copiar/pegar este código en el campo URL:
javascript:(function(){var a=window,b=document,c=encodeURIComponent,d=a.open('http://www.google.com/bookmarks/mark?op=edit&output=popup&bkmk='+c(b.location)+'&title='+c(b.title),'bkmk_popup','left='+((a.screenX||a.screenLeft)+10)+',top='+((a.screenY||a.screenTop)+10)+',height=420px,width=550px,resizable=1,alwaysRaised=1');a.setTimeout(function(){d.focus()},300)})();
Supongo que irán mejorando el producto pero de momento sirve.
martes, 30 de agosto de 2011
Sincronizar reloj de servidor con ntp diariamente
cd /etc/cron.daily
sudo vi pon-en-hora.sh
#!/bin/sh
ntpdate hora.roa.es
Guardamos y le damos permisos:
sudo chmod 700 pon-en-hora.sh
Y ya tenemos el servidor con el reloj en hora cada día.
sábado, 6 de agosto de 2011
El futuro de django
miércoles, 3 de agosto de 2011
Errores en los comunicados de prensa de la ESA
03-08-2011 09:00 AM CEST
El observatorio espacial Herschel de la ESA ha encontrado moléculas de oxígeno en una cercana nube de formación de estrellas. Este descubrimiento es la primera prueba irrefutable de la existencia de oxígeno molecular en el espacio. Con él concluye una larga búsqueda, aunque da pie a nuevas cuestiones.
martes, 2 de agosto de 2011
La suma de la serie de los primeros n números enteros
Contaba Karl Friederich Gauss 10 años cuando un día en clase y en vista de que se portaban mal, el maestro les castigó a que sumaran los cien primeros números pensando que estarían un largo tiempo sin molestar. Efectivamente, todos bajaron la cabeza hacia sus cuadernos y empezaron las largas sumas pero al cabo de unos minutos un alumno levantó la mano y dijo: Ya está profesor. El malhumorado maestro pidió al alumno el resultado -- cinco mil cincuenta Sr. maestro -- contestó Gauss. Pensando que había hecho trampas el profesor exigió a Gauss que explicara cómo había conseguido la suma tan rápido, a lo que el niño contestó:
En vez de sumar 1+2+3+... he hecho 1+100=101, 2+99=101, 3+98=101 y al darme cuenta de que siempre sumaba ciento uno sólo he tenido que calcular 50 veces ciento uno (50*101=5050)...
Sólo podemos imaginar la cara del profesor al escuchar semejante razonamiento de boca de un niño de 10 años, pero cuenta la historia que así empezó la leyenda del "príncipe de la matemáticas".
lunes, 25 de julio de 2011
36 años de la Viking I. El día que visitamos Marte.
El 20 de julio de 1976, la sonda Viking I de la NASA tomó tierra sobre la superficie de Marte. Era la primera vez que un ingenio humano tocaba la superficie del planeta rojo con éxito y tomaba fotografías de alta resolución así como medidas atmosféricas y de composición del suelo.
viernes, 22 de julio de 2011
Adéu al transbordador
Disturb us, Lord, when
We are too well pleased with ourselves,
When our dreams have come true
Because we have dreamed too little,
When we arrived safely
Because we sailed too close to the shore.
Disturb us, Lord, when
With the abundance of things we possess
We have lost our thirst
For the waters of life;
Having fallen in love with life,
We have ceased to dream of eternity
And in our efforts to build a new earth,
We have allowed our vision
Of the new Heaven to dim.
Disturb us, Lord,
to dare more boldly,
To venture on wider seas
Where storms will show your mastery;
Where losing sight of land,
We shall find the stars.
We ask You to push back
The horizons of our hopes;
And to push into the future
In strength, courage, hope, and love.
Francis Drake, 1577.
Hasta siempre, transbordador.
jueves, 23 de junio de 2011
Ejecutar scripts mysql a lo Unix
mysql -u root -p -h localhost nombre_bd < script.sql
y otra
cat script.sql | mysql -u root -p -h localhost
lunes, 20 de junio de 2011
Cuidado con el directorio de instalación de django
from distutils.sysconfig import get_python_lib;print get_python_lib()
y muestra
/usr/lib/python2.6/dist-packages
Peeero, en realidad en ubuntu se instala en
/usr/local/lib/python2.6/dist-packages
o
/usr/lib/pymodules/python2.6/django
¿Cómo podemos saber la localización de este directorio?. Pues usando la librería sys, que mantiene la localización del __init__.py de cada import:
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys, os, django
>>> sys.modules['django']
module 'django' from '/usr/local/lib/python2.6/dist-packages/django/__init__.pyc'
Sacado de esta entrada de stackoverflow http://stackoverflow.com/questions/2647862/how-can-i-tell-what-directory-an-imported-library-comes-from-in-python
domingo, 19 de junio de 2011
Opciones para programación con vi / vim
syntax on
set number
set expandtab
set tabstop=4
set shiftwidth=4
set nowrap
set foldmethod=marker
set smartindent
set mouse=a
set foldmethod=indent
set foldlevel=99
autocmd BufRead *.py set makeprg=python\ -c\ \"import\ py_compile,sys;\ sys. stderr=sys.stdout;\ py_compile.compile(r'%')\"
autocmd BufRead *.py set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z %[%^\ ]%\\@=%m
autocmd BufRead *.py nmap :!python %
map ^T :Texplore <CR>
Para sacar el control+T hacemos ctrl+v y luego ctrl+t.
Con esta configuración:
:make para ver errores de sintaxis.
za hace fold/unflod dentro de un método
:retab cambia todos los tabs por espacios o al contrario, según config actual
Window splits
Para dividir la pantalla y no tener que estar arriba y abajo con el mismo fichero:
Vertical Split : Ctrl+w + v
Horizontal Split: Ctrl+w + s
Close current windows: Ctrl+w + q
Unos cuantos links
Un montón de trucos.
El wiki de los trucos.
El clásico Turning Vim into a modern Python IDE.
Artículo Beginner's guide to Vi Improved
sábado, 4 de junio de 2011
Cambiar tamaño de disco en qemu kvm
1.- crear disco de destino del tamaño deseado p.e. 60G
qemu-img create -f qcow2 destino.qcow2 60G
2.- arrancamos gparted con un sistema con los dos discos
qemu -hda inicial.qcow2 -hdb destino.qcow2 -cdrom=gparted.iso -boot d
3.- con el gparted hacemos copiar/pegar de un disco a otro con el nuevo tamaño deseado
(tarda bastante si los discos son grandes)
4.- comprobamos que boota y nuevo tamaño de disco
qemu -had destino.qcow2
hacemos df -h para comprobar nuevo tamaño
Si el nuevo dominio no arranca podemos usar la distribuición rescatux y regrabar el grub en la MBR (gràcies Victor ;-))
qemu -hda destino.qcow2 -cdron=rescatux.iso -boot d
Pasar de VirtualBox a KVM o Xen
convertim vmdk de virtual box a raw:
VBoxManage internalcommands converttoraw aaa.vmdk file.raw
comprbar que boota
qemu -had file.raw
Convertimos raw a qcow2
qemu-img convert file.raw -O qcow2 imatge.qcow2
comprobar que boota
qemu -had imatge.qcow2
Cómo virtualizar con ubuntu kvm y no morir en el intento
Community KVM installation
sábado, 21 de mayo de 2011
Python, más aritmética con meses
def suma_mes(current_date, month_step):
""" suma month_setp mesos a current_date """
carry, new_month=divmod(current_date.month-1+month_step, 12)
new_month+=1
return current_date.replace(year=current_date.year+carry, month=new_month)
¿Cuántos días faltan para el mismo día de hoy del mes que viene?
>>> print (suma_mes(datetime.date.today(), 1)-datetime.date.today()).days
Sumar un mes con python
>>> 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
>>>
lunes, 4 de abril de 2011
Ubuntu One trabaja con IIS!!!
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.
viernes, 11 de marzo de 2011
Django: Evitar error en el administrador "decoding Unicode is not supported"
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
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
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
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
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.