1. ¿Cómo probar las páginas de errores (404, etc...) en desarrollo?

    Para ver esas páginas de error, hay que desactivar la opción DEBUG de la configuración. Pero si lo hacemos, los contenidos estáticos dejan de servirse, así que no podemos estar seguros de como se verán las páginas finales, a no ser que instalemos nuestro propio servidor de contenidos estáticos.
    O, por otro lado, podemos usar el flag insecure al llamar a runserver:
    manage.py runserver --insecure
    

    Esto obliga al servidor de desarrollo a servir los ficheros a partir de los directorios static de las aplicaciones, aunque la variable settings.DEBUG sea False.

    De ninguna manera debemos usar este truco para poner en explotación un servidor de desarrollo de Django. Citando la documentación oficial:

    [...] By using this you acknowledge the fact that it’s grossly inefficient and probably insecure. This is only intended for local development, should never be used in production [...]

    ¿Cómo analizar las consultas SQL que está realizando Django?

    Normalmente el primer paso para poder optimizar Django consiste en analizar el número de consultas, así como los tiempos de ejecución de las mismas. Para ello hay una extensión muy recomendable: Django-debug-toolbar.

    The Django Debug Toolbar is a configurable set of panels that display various debug information about the current request/response and when clicked, display more details about the panel’s content.
    Lo ideal es poner esta app en desarrollo, y no en el despliegue final. Véase la siguiente entrada

    ¿Cómo tener diferentes entornos de desarrollo/explotación/pruebas?

    Mi solución actual, adaptada del muy recomendable libro Two Scoops of Django, consiste en tener un settings.py que será el que se use en despliege y luego un fichero development.py, que simplemente importa todo el contenido del settings.py y realiza las modificaciones que crea oportunas.
    Por ejemplo:

    from main.settings import *
    
    DEVELOPMENT = True
    
    INSTALLED_APPS += (
        'debug_toolbar',
        )
    
    Para arrancar en desarrollo uso:
    manage.py runserver --settings=main.development
    

    ¿Cómo hago para que mi método booleano se vea bonito en el admin?

    Esta documentado, pero a menudo resulta complicado de encontrar. Si escribimos un método de un modelo que devuelve solo True o False, y lo consultamos en el admin, este nos muestra texto. Sin embargo, para campos definidos como booleanos (BooleanField) nos muestra un icono. Podemos hacer que utilice esos mismos iconos si añadimos un atributo boolean al método.
    por ejemplo:
    def nacio_en_bisiesto(self):
        year = self.birthday.year
        return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
    
    nacio_en_bisiesto.boolean = True
    

    ¿Cómo hago para mostrar mi propio contenido html en el admin?

    Para que el admin interprete cualquier texto producido por un método como Html, sin escaparlo, debemos asignarle al método en cuestión el atributo allow_tag a True. Es recomendable que nos escudemos de posibles fallos de seguridad usando la función format_html() siempre que incluyamos en la salida texto generado por el usuario final.
    Por ejemplo:

    def colored_name(self):
        return format_html('<span style="color: #{};">{} {}</span>',
                        self.color_code,
                        self.first_name,
                        self.last_name)
    
    colored_name.allow_tags = True
    
    0

    Añadir un comentario

  2. Taller Introducción a Django

    En las instalaciones de Kreitek / El Andén realizaremos un taller de introducción a Django.

    • Serán cuatro sesiones, las tardes de los viernes, 25 de septiembre, y 2, 9 y 16 de octubre. las sesiones serán de unas tres horas, incluyendo un descanso para que el personal no desfallezca.

    • Será necesario llevar un portátil, si puede ser al menos con Python instalado. Versión 2.7 o 3.4, la que se prefiera.

    • El taller no es gratuito, valdrá 10€ para los no socios del andén y 5€ para los socios. La totalidad del importe irá destinada Al Anden.

    Durante el taller realizaremos una aplicación web completa con frontend, backend, modelo de datos y servicios API REST. Se intentará dar una visión extensa de Django, aunque no podremos profundizar mucho en cada tema.

    Más información aquí:

    http://goo.gl/HI5MhV

    Pero... ¿Cómo se llega a El Taller K / El Andén?

    Está perfectamente explicado aquí: Taller Kreitek: Donde estamos

    Temario

    Si se producen cambios en el mismo, los publicaremos en el enlace anterior, pero esto es lo que hay pensado por ahora:

    Viernes 25, septiembre

    Introducción a Django. Estructura de una aplicación web. Frameworks web. Breve introducción a Python. Instalación de Django. La estructura MVC (Modelo-Vista-Controlador). Nuestro "Hola, mundo" en Django. Qué es una vista. El objeto request. Presentación de la aplicación que vamos a construir en el taller. Risas.

    Viernes 2, octubre

    Bases de datos. El modelo relacional. Normalización de bases de datos relacionales. Modelos en Django. Campos. El mapeador objeto-relacional en Django. Consultas sencillas a la base de datos. Consultas no tan sencillas. SQL Crudo. Señales y eventos. La aplicación django.contrib.admin. Modelos incluidos: Autentificación y usuarios, grupos, mensajes. Agasajos y loas a los que no han abandonado después del primer día; técnicas de Vudú a lo que si.

    Viernes 9, octubre

    El sistema de plantillas. Etiquetas (tags) y filtros (filters). Limitaciones --intencionadas-- del sistema de plantillas. Herencia de plantillas. Sistema de carga de plantillas. Creación de nuestras propias etiquetas y filtros. Adaptar un tema de Wordpress a Django. Uso de frameworks como Bootstrap o Purecss. Formularios. Controles y widgets. Formularios desde modelos. Debate: "Cuando usar Django y cuando no".

    Viernes 16, octubre

    Crear comandos de administración. Ficheros urls.py anidados. Cambios en el sistema de base de datos (migrate). Vistas genéricas. Vistas basadas en clases. Generar contenidos que no son HTML. Crear una API Rest. Despliegue de Django en explotación. Cachés y escalabilidad. Middleware. Internacionalización. Tests con Django. Apps de django recomendables. Té y pastas.

    Molón Cartel diseñado por @torehc20

    0

    Añadir un comentario

  3. Este viernes, 5 de junio, a partir de las 19:00, tendremos una nueva reunión de PyBirras Tenerife. Hablaremos, como siempre, de Python, de cervezas, de lo humano y de lo divino (por ese orden). Además, tendremos no una, ni dos, sino tres minicharlas:

    Esta vez nos han invitado a alojar la reunión el equipo de G·koworking, en La Laguna. El lugar es:

    Plaza San Honorato, 3, CP 38203
    La Laguna / Tenerife
    Mapa

    Es muy cerca del centro de La Laguna, a menos de 5 minutos de la última parada del tranvía en La Trinidad, en un emblemático local, que durante muchos años fue la "Academia Lázaro".

    Como siempre, recordarles que la asistencia es totalmente gratuita, pero se agradecería confirmación de la asistencia, ya sea en el meetup del evento, o vía un twitter a @jileon.

    0

    Añadir un comentario

  4. Por fin vemos lo que había detrás de la fachada...

    Visto en la lista de correo de Expatriados.

    0

    Añadir un comentario

  5. Este próximo viernes vamos a realizar el tercer encuentro PyBirras. Las PyBirras son reuniones informales en la que hablamos de programación en general y del lenguaje Python en particular. Y beberemos cervezas artesanales canarias (solo si quieres, no es obligatorio [Pero está muy rica]).

    En esta reunión hablaremos de las charlas que más nos impactaron en la última PyConEs, y de algunos desarrollos interesantes hechos en El Anden. Y de la vida, el Universo y lo demás.

    La asistencia es totalmente gratuita, pero si que te agradecería que confirmaras la asistencia en este meetup:

    http://www.meetup.com/Agile-Canarias/events/220564873/

    o vía un twitter a @jileon.

    PyBirras Tenerife
    Viernes 13 de marzo de 2015
    18:30 hasta 20:00
    Anden Sin límite
    Carretera Cuesta Taco, 67, Santa Cruz de Tenerife

    Después del evento proyectaremos, para el que quiera quedarse, el documental Indie Game: The Movie. Y pediremos pizza. Y más cervezas.

    0

    Añadir un comentario

  6. La edición anterior no pude participar y me pasé el resto del año arrepentido, esta vez no se repetirá. Con ustedes mi aportación al Big Culo Day 2015: el genial Vittorio Giardino y uno de los culos más redondos de la historia del Comic, Little Ego:


    Extra Bonus: Un boceto de Milo Manara de la famosa pose de SpiderWoman, vista desde desde otro ángulo, demostrando una vez más que la lujuria no está solo en el ojo que ve, también está en el punto de mira.

    0

    Añadir un comentario

  7. This is my first post in english. I'm doing this as a way to improve my English. If you see something wrong or strange in this article, I'll be pleased if you point it in the comments. Thank you very much in advance.

    Nota: Hay una versión en español de este artículo aquí: Django Tip: Modificar la sentencias SQL generada por un queryset.

    The extra method of the queryset objects allows us to add some modifications to the SQL statement it will use. Specifically, extra can be used to add new fields to the Select clause, add Tables or Joins to the From clause, and/or add new conditions to the Order By clause.

    Suppose we have the usual sock of items for sale, something like that:

    class Item(Model):
        id = AutoField(primary_key=True)  # I like to specify the Id.
        description = CharField(max_length=200)
        price = DecimalField(max_digits=12, decimal_places=2)
        created_at = DateTimeField(auto_now_add=True)
    

    We can add a calculated field, just to distinct between items with prices below 5 € of items with a higher price (maybe we want to stamp a low-price icon on the result page, for example). We can use the extra method to add a new calculated field, named "low_price", with the following code:

    Item.objects.extra(select={'low_price':'pvp < 5.0'}).all()
    

    Under the hood, what we are doing is transforming the Django generated SQL statement from this:

    SELECT app_item.*
      FROM app_item;
    

    to this:

    SELECT app_item.*, (pvp <= 5.0) AS low_price
      FROM app_item;
    

    We can add many different calculated fields, either using the dictionary passed as the value of the select parameter, or making several calls to the extra method. For example, if we want to classify the items on three divisions (cheap, under 5€; medium, between 5€ and 100€; and expensive, above 100€), we may do something like this:

    Item.objects.extra(select={
        'low_price':'pvp < 5.0',
        'mid_price':'pvp between 5.0 and 100.0',
        'low_price':'pvp > 100.0',
        }).all()
    

    or this other way:

    Item.objects  \
        .extra(select={'low_price':'pvp < 5.0'})  \
        .extra(select={'mid_price':'pvp between 5.0 and 100.0'}) \
        .extra(select={'low_price':'pvp > 100.0'})  \
        .all()
    

    Result must be the same in either case.

    Reality is that we can get this data with a really simple method on the Item class, but in some cases, it could be very useful to make the Database do the calculations for us.

    Clearly, we can add subqueries as new fields in the select clause, which increase the possibilities. As an example, suppose our application have a model to store the ratings our clients give to our products, something like this:

    class Score(models.Model):
        id = AutoField(primary_key=True)  # Yes, I know, It's needless...
        item = ForeignKey(Item)
        rate = SmallIntegerField()
    

    We can do a search over our stock, adding the mean rate of every product, calculated by the database itself:

    Item.objects.extra(select={
        'mean_rate':'''
            SELECT AVG(app_score.rate)
              FROM app_score
             WHERE app_score.item_id = app_item.id
             '''
        }).all()
    

    We can do the same in our Django Code, writing a simple method in the Item class. But we need a new SQL query to get all the scores of an item, and calculating the average after that.

    If we obtain 10 items as a result, for example, we will count up to 11 sql queries to the Database, one for the original search, and one for every item in the result, to get the list of scores. And we have to make the calculation ourself. If we let the Database to make the operation for us, we will count just one SQL query. The difference in performance can be noticeable.

    Beware this techniques have a dangerous face: we have linked our code to the Database management system more strongly. That implies more dependencies and more danger. If we use proprietary extensions to the SQL syntax, we got a potential break point. Even a simple call to get the current timestamp -Every Database define his own names: sysdate in Oracle, now() in postgreSQL, current_timestamp in Microsoft SQL Server, to name just a few- will break if we migrate to another database brand.

    Nevertheless, it's useful to known that we have this ability. It depends of ourselves to use it or not. Just remember this three little advices:

    • Explicit is better than implicit. (Tim Peters)
    • Special cases aren't special enough to break the rules ... Although practicality beats purity. (Tim Peters)
    • With great power comes great responsibility (Benjamin Parker)

    Note: the use of extra to modify the FROM and WHERE clauses is better explained, among other interesting information, in the official docs: Django Query Set API reference - extra.

    0

    Añadir un comentario

  8. Note: There is a english version of this post here: Django Tip: Modify the generated SQL statement of a queryset

    El método extra de los queryset nos permite realizar algunas modificaciones en las sentencias sql que ejecuta. En concreto nos permite añadir campos a la cláusula SELECT, o tablas y joins a la cláusula FROM, o condiciones a la cláusula ORDER BY.

    Supongamos, por ejemplo, que tenemos una tabla de productos a la venta, algo como esto:

    class Item(Model):
        id = AutoField(primary_key=True)  # Me gusta especificar la clave
        descripcion = CharField(max_length=200)
        pvp = DecimalField(max_digits=12, decimal_places=2)
        alta = DateTimeField(auto_now_add=True)
    

    Podemos añadir un campo calculado que nos indique si los precios son inferiores a 5.0 (quizá queremos marcar estos productos en la página con un icono de "low-price", por ejemplo). Para ello, podemos añadir un campo calculado al select de la query usando extra, como en el siguiente ejemplo:

    Item.objects.extra(select={'low_price':'pvp < 5.0'}).all()
    

    Lo que estamos haciendo es que la sentencia SQL generada por Django pase de esto:

    SELECT app_item.*
      FROM app_item;
    

    a esto:

    SELECT app_item.*, (pvp < 5.0) AS low_price
      FROM app_item;
    

    Podemos pasar varios campos calculados en el diccionario especificado por el parámetro select, o hacer varias llamadas a extra. Por ejemplo, si queremos clasificar los precios en tres bandas, (baratos, por debajo de 5 euros; medios, entre 5 y 100 euros y caros, por encima de 100 euros), podemos hacerlos así:

    Item.objects.extra(select={
        'low_price':'pvp < 5.0',
        'mid_price':'pvp between 5.0 and 100.0',
        'low_price':'pvp > 100.0',
        }).all()
    

    O así:

    Item.objects  \
        .extra(select={'low_price':'pvp < 5.0'})  \
        .extra(select={'mid_price':'pvp between 5.0 and 100.0'}) \
        .extra(select={'low_price':'pvp > 100.0'})  \
        .all()
    

    El resultado debería ser el mismo en los dos casos.

    Es verdad que podemos realizar este calculo de bandas de precios en un simple método de la clase Item, pero en ocasiones puede sernos útil o necesario que determinadas operaciones las haga la base de datos por nosotros.

    Obviamente también podemos pasar subconsultas como campo añadido al select, que nos da aun más posibilidades. Por ejemplo, supongamos que en nuestra aplicación tiene otro modelo con las puntuaciones que nuestros clientes asignan a nuestros artículos, algo como esto:

    class Score(models.Model):
        id = AutoField(primary_key=True)  # Si, ya lo sé, no hace falta...
        item = ForeignKey(Item)
        rate = SmallIntegerField()
    

    Podemos realizar una consulta sobre artículos e incorporar la puntuación media de cada uno, calculada directamente por el gestor de la base de datos:

    Item.objects.extra(select={
        'mean_rate':'''
            SELECT AVG(app_score.rate)
              FROM app_score
             WHERE app_score.item_id = app_item.id
             '''
        }).all()
    

    Si quisiéramos hacerlo desde Django, con un método de la clase Item, por ejemplo, tendríamos que realizar primero una consulta para obtener todas las puntuaciones de un artículo, y luego calcular la media.

    Si lo hacemos para una consulta cuyo resultado final fueran 10 artículos, por ejemplo, tendríamos que hemos realizado 11 consultas SQL a la base de datos, haciendo además el cálculo nosotros, por una sola consulta, si los cálculos los realiza el SGBD. La diferencia en rendimiento puede ser considerable.

    Estás prácticas también tienen su lado peligroso: hemos vinculado más nuestro código al gestor de base de datos que estamos usando, con las dependencias y peligro que eso conlleva. Si usamos extensiones propietarias de la base de datos para realizar la consulta, aunque sea algo tan simple como utilizar la marca de tiempo de la base de datos (Que cada gestor se empeña en definir de forma diferente, sysdate en Oracle, now() en postgreSQL, current_timestamp en Microsoft SQL Server, por citar solo unos pocos ejemplos), ya tenemos un punto de ruptura si pretendemos migrar de gestor.

    En cualquier caso, es útil saber que tenemos esta capacidad, ya depende de nosotros si queremos emplearla o no. Recuerda solo estos tres consejos:

    • Explícito mejor que implícito (Tim Peters)
    • Los casos especiales no son tan especiales como para romper las reglas ... pero lo práctico vence a lo ideal (Tim Peters)
    • Todo gran poder conlleva una gran responsabilidad (Benjamin Parker)

    Nota: El uso de extra para modificar las cláusulas FROM y WHERE está explicado, junto con muchas otras cosas interesantes, en la documentación oficial: Django Query Set API reference - extra.

    0

    Añadir un comentario

  9. Reconozco que tengo un problema con la prensa de este país: No me creo su independencia.

    La última patochada son las airadas protestas porque el nuevo gobierno de Grecia no cuenta con mujeres entre sus miembros. Que haya subido el salario mínimo o haya garantizado la electricidad a los más pobres no importa. Peor aun, es populista. Permitidme que os lo diga: ¡Qué falso os queda!

    • ¿Sabes cuántas mujeres había en el gobierno anterior de Grecia? ¿Y en el anterior a este? ¿Y en el anterior al anterior a este? (Spoiler alert: Más bien tirando a pocas tirando a ninguna).

    • ¿Por qué no os preocupó ENTONCES? ¿Dónde estaba vuestra justa ira? ¿Cómo se os pudo pasar tan por alto como para no denunciarlo NI UNA SOLA VEZ?

    • ¿Cuantas mujeres hay ahora mismo en el Gobierno de EEUU? (Spoiler alert: Una. En un ministerio de chichinabo, por cierto)

    • ¿Por qué no os preocupa AHORA? ¿Por qué no os rasgáis las vestiduras por el machismo patriarcalista de Obama?

    Son preguntas sencillas pero no os preocupéis, ya contesto yo por vosotros: La república Griega y su gobierno os chupa un pie. La igualdad de la mujer os importa tres cominos. La Equidad os la refinfanfinfla pero bien. No sois más hipócritas porque no entrenáis.

    En resumen: No cuela.

    PD: De propina, un pequeño cuento (after Augusto Monterroso):

    Cuando el dinosaurio despertó, Podemos seguía allí.

    PD2: Cuando hablo de prensa, no incluyo a artefactos bélicos como La Razón, Libertad Digital y similares, manojos de papeles/bits juntados al tuntún para hacer bulto y mantener la ilusión entre los más adoctrinados, medios comprados (y vendidos) desde su mismo nacimiento. Hablo de cabeceras con bagaje histórico, como El País, ABC o El Mundo (No enlazo porque ahora es delito, se siente). Los que ahora agachan la cabeza y obedecen prestos la voz de su amo, mientras se quejan de que las ventas en papel bajan. Y se pregunta el porqué.

     

    0

    Añadir un comentario

  10. No creo que la foto sea real...*

    ... pero quizá sea el origen de un nuevo y exitoso Hashtag: #SpainWTF

    *No voy ni a molestarme en comprobarlo.

    0

    Añadir un comentario

Archivo del blog
Etiquetas
Etiquetas
Enlaces interesantes
Cargando