Como tener un IDE completo usando Vim (Vimsual Studio)

Este artículo es un escueto resumen-chuleta que nos permitirá configurar rápidamente el editor Vim como un IDE completo, incluyendo:

  • Navegador de ficheros de proyecto
  • Navegador de símbolos del lenguaje (clases, métodos, miembros...)
  • Navegador de ficheros externos
  • Autocompletado inteligente
  • Pestañas
  • Navegador de ficheros recientes
  • ...y más.

Pincha abajo para leer el artículo completo.

Continua dentro; pincha para leerlo completo (2680 palabras)

Why is a Bad Idea to inherit the Product model in Satchmo (and how to do it right)

I've seen on some articles on the web that one of the ways people is extending the Product model in Satchmo is inheriting from it.

I used it once and it was a Bad Idea, and I will explain why. With a little luck Google will index this and show this to people looking for ways to override Product because currently if one looks at the results it's like that inheriting Product is the only way.

Probably one of the reasons that people do this is because in Django is very common to extend the django.auth User model inheriting it. But this case is different, because:

  • Django doesn't ship with default templates
  • The User model in Django is only used on a few default views where only the User fields have sense.
  • The User mode in Django is not linked to any other Django default models.
  • Inheriting User allows for cleaner implementations when you have lots of different user types and roles; using Profiles you would have to implement it using an intermediate profile which for every type of user links to the real profile.

Inheriting Product is a bad idea in Satchmo because:

  • Satchmo ships with lots of default Templates. Usually most sites will rewrite some of these templates, but...
  • Those templates are generated by lots of default views. Most of those use Product or some object linked with Product, so the templates will receive objects that only have Product fields, even if they were generated using your custom model. So you'll be unable to access any field of your model inside the template, except rewriting the views (and the urls pointing to the views.)
  • There are very important models like Order, OrderItem, CartItem and others linked to the Product model. So you'll have to inherit those two, along with rewriting (again!) the templates and views that use them.
  • You don't gain anything by inheriting Product compared with the Satchmo standard way.

So what is my proposal for extending a Product object? Easy, just use what Satchmo documentation propose.

For example if we want to extend our shop products adding the "code" and "provider" fields we can follow these precise steps:

On your core app models.py, add the extension model (take care to don't call it "Product" or it will clash with Satchmo product model!):

from django.db import models
from django.utils.translation import ugettext_lazy as _

import django.db.models.signals as djangosignals
from product.models import Product
from satchmo_store.contact.models import Organization

class LocalProduct(models.Model):
    product = models.OneToOneField(Product, verbose_name=_('Base Product'))

    code = models.CharField(verbose_name=_('Code'), max_length=32, blank=True, null=True)
    suplier = models.ManyToManyField(Organization, verbose_name=_('Supplier'), blank=True, null=True)

    def _get_subtype(self):  return 'LocalProduct'

    def __unicode__(self):
        if self.code:
            return u"%s [%s]" % (self.product.name, self.code)
        else:
            return u'%s' % self.product.name

    class Admin: pass

    class Meta:
        verbose_name = _('LocalProduct')
        verbose_name_plural = _('LocalProducts')

import config

Add this on your core app config.py (change "localsite" for your app name):

from django.utils.translation import ugettext_lazy as _
from livesettings import config_get

PRODUCT_TYPES = config_get('PRODUCT', 'PRODUCT_TYPES')
PRODUCT_TYPES.add_choice(('localsite::LocalProduct', _('Local Product')))

If you want the LocalProduct to show on the admin automatically linked when you add or edit a product (hint: you do) then add this to you app admin.py, configuring the admin display fields to your taste:

from django.contrib import admin
from product.models import Product
from models import LocalProduct
from livesettings import config_value
from product.admin import ProductAttribute_Inline, Price_Inline, \
    ProductImage_Inline, ProductTranslation_Inline, ProductOptions

class LocalProduct_Inline(admin.StackedInline):
    model = LocalProduct
    extra = 1

class LocalProductOptions(ProductOptions):
    exclude = ('slug', 'sku', 'meta', 'length', 'length_units',
               'width', 'width_units', 'height', 'height_units',
               'weight_units', 'related_items', 'also_purchased',
               'date_added', 'taxable', 'taxClass', 'shipclass',
               'site',)

    fieldsets = (
        (None, {'fields': ('name', 'category', 'description', 
        'short_description', 'weight', 'active', 'featured', 
        'items_in_stock', 'total_sold','ordering',)}),
        )

    list_display = ('name', 'items_in_stock', 'unit_price')
    list_display_links = ('name',)
    search_fields = ['name', 'description', 'short_description']
    inlines = [LocalProduct_Inline, Price_Inline, ProductImage_Inline]
    filter_horizontal = ('category',)

    if config_value('LANGUAGE','SHOW_TRANSLATIONS'):
        inlines.append(ProductTranslation_Inline)

admin.site.unregister(Product)
admin.site.register(Product, LocalProductOptions)

Finally, if you want to have something done when the Product saves, instead of overriding save on an inheriting model save(), use Django signals:

models.py (at the end):

from satchmo_store.shop import get_satchmo_setting, signals
from listeners import *

djangosignals.pre_save.connect(product_pre_save, sender = Product)

listeners.py:

def product_pre_save(sender, instance, **kwargs):
    if instance.pk is None:
        instance.site = Site.objects.get(pk=1)
        instance.taxable = True
        instance.taxClass = TaxClass.objects.get(pk=1)
        instance.date_added = datetime.date.today()
        if not instance.has_full_weight:
            instance.weight = Decimal(0)
            instance.weight_units = 'grs'

And that's it. You have an extended Product without any of the pains. Now if you want to access some of the new fields from a template you just do: product.localproduct.code, without the need to overwrite any Satchmo view or inheriting lots of Product-related objects.

Compartir/Guardar/Bookmark

Vim: explicación de ventanas, pestañas y buffers

[Pincha aquí para ver otros artículos sobre Vim]

Cuando uno empieza a usar el potentísimo editor de texto Vim y consigue pasar de esa primera fase en la que nos horrorizamos de que todo sea tan distinto y poco intuitivo a la segunda fase en la que entendemos la filosofía de trabajo del editor (y es resto de editores nos empiezan a parecer poco intuitivos), es aún posible que nos líemos un poco con los conceptos de Vim de vista, ventana, buffer y pestaña.

Vamos a ver que es cada cosa y cómo suelen usarlas los usuarios avanzados de Vim, pero antes de explicarlo pongo un dibujito muy mono (pincha para ampliarlo mucho, es grande pero ocupa poco):

  • Vista: La vista en Vim es lo que vemos en el monitor. Una vista estará siempre dentro de una pestaña (si sólo tenemos una pestaña abierta la vista estará en la única pestaña) y a su vez puede contener una o más ventanas dentro.

  • Ventanas: En Vim una ventana es una subdivisión de la pantalla total que el programa puede usar. Es decir, si estás editando un fichero entero y éste ocupa toda la pantalla que ocupe el Vim, tienes una ventana. Si haces :split o :vsplit, tendrás ahora dos ventanas, viendo el mismo fichero (buffer). Si ahora en una de ellas haces de nuevo :split, tendrás tres ventanas. La utilidad de las ventanas es que nos permiten ver varios buffers o varias partes de un mismo buffer simultáneamente, lo cual en ocasiones es muy útil para programar. Como mínimo vas a tener siempre una ventana porque si cierras la última se cierra el programa y en cualquier momento estamos trabajando a través de una (o varias) ventanas. Incluso cuando estamos en una pestaña, realmente estamos en una ventana que está dentro de una pestaña.

  • Buffers: Los buffers son el concepto más importante de los de esta lista porque son los que contienen realmente los ficheros que abrimos, por lo que podemos pensar en los buffers como los ficheros cargados en memoria; si cerramos un buffer se cierra realmente el fichero y si abrimos un buffer se abre otro fichero. Esto no sucede con ventanas y pestañas porque cuando cerramos una pestaña a través de la cual estamos viendo un buffer el buffer sigue existiendo porque sólo hemos cerrado la ventana. Podemos hacer una metáfora diciendo que las ventanas son las ventanas de una casa y los buffers son las personas; si cierras la ventana la persona sigue estando detrás. La única excepción es cuando cerramos la última ventana abierta en la única pestaña que queda; en ese caso Vim considera que ya no vamos a trabajar más, dado que siempre trabajamos a través de una ventana, y por lo tanto cierra también todos los buffers que hubiera abiertos.

  • Pestañas: Las pestañas, una funcionalidad relativamente reciente de Vim permiten mantener simultaneamente varias vistas, cada una de las cuales puede contener una o más ventanas, y en esa única o múltiples pestañas podemos estar viendo uno o más buffers.

Compartir/Guardar/Bookmark

Mini visión general y opinión sobre Django

Django es un en entorno de programación web que lleva varios años funcionando aunque ha sido ahora (2009) cuando ha visto un auge importante en su uso debido a la salida de la primera versión estable, la 1.0. En este artículo quiero dar una visión general y resumida de como está estructurado y como funciona, así como mi opinión personal-profesional. Es importante destacar que este artículo no es un curso ni un tutorial de Django, aunque sin duda tener unas nociones de como funciona Django en conjunto ayudará al que a continuación quiera aprenderlo a fondo.

[El artículo sigue en el interior]

Continua dentro; pincha para leerlo completo (2745 palabras)

Re-Estrenando web: Juanjoalvarez.net 3.0

¡Hay parto!

Hoy estreno la tercera versión de mi web juanjoalvarez.net. Aunque todo parezca igual estéticamente (la plantilla existente me gustaba así que la he conservado) por debajo absolutamente todo es nuevo.

La primera versión de esta página, allá por los años 90, eran todo contenidos estáticos cargados usando una plantilla base que hacía $includes con PHP de cada página. Probablemente tuviera gif animados...

La segunda versión, a mediados de 2000, estaba en el gestor de contenidos drupal y cumplió su función durante unos cuantos años. Pero tenía el problema de que cada vez que quería cambiar algo en el código para incluír una nueva funcionalidad, tenía que estar un par de horas sólo para ver por donde empezar porque no soy experto en el código de Drupal, así que como últimamente he estado aprendiendo bastante bien el framework web Django y usándolo en dos proyectos personales y uno profesional, decidí migrar todo.

Hay que decir que Django no es exactamente lo mismo que Drupal pues el primero es un framework web (de más bajo nivel) mientras que el segundo es un gestor de contenidos. Sin embargo la migración completa me ha llevado sólo dos días, usando módulos que ya estaban hechos por terceros o hechos en alguno de los otros proyectos Django en los que participo (por mi o por mis compañeros). Y ésto no sólo conservando toda la funcionalidad que usaba de Drupal sino añadiendo además funcionalidad adicional como la página y la caja con los tweets de mis dos cuentas de Twitter o la página con la lista de noticias y chorradas que voy compartiendo en el Google Reader.

Aparte de las funcionalidades nuevas la página debería ser mucho más rápida (y lo es, según el Google Page Speed y el YSlow) debido en parte al nuevo hosting y en parte a que ya no cargo contenidos externos como la caja de compartidos de Google (que no hace falta con la nueva caja) o la de LibraryThing. Para suplir la funcionalidad que me daba la cajita de LibraryThing (mostrar los últimos libros leídos y reviews) planeo escribir una aplicación Django para hacer reviews de contenidos culturales (libros, películas, música).

Además las entradas del gestor del contenido soportan entradas escritas en varios idiomas, dos formatos de edición (HTML puro o Markdown) y otras cosas que con Drupal no tenía, o no podía tener sin mucho dolor.

Lo que no he podido migrar de momento son los comentarios. Es una pena porque había algunos interesantes y que aportaban cosas (sobre todo en las páginas de programas) veré si más adelante puedo migrarlos de alguna forma aunque sea metiéndo aquellos que considere interesantes a manopla.

Más adelante escribiré un comentario con una revisión general de Django con mi opinión, pero de momento se puede resumir en que estoy feliz como una perdiz con el descubrimiento.

Compartir/Guardar/Bookmark

« Anterior 1 2 Next »