Source

gnocchi-catalogue / catalogue / models.py

Full commit
from django.db import models
from django.core.urlresolvers import reverse
from django.core.exceptions import ValidationError
from django.contrib.contenttypes import generic
from django.utils.translation import ugettext_lazy as _

from datetime import datetime
from decimal import Decimal

from taggit.managers import TaggableManager

from gnocchi_tools.attr import AttrHelper

class Product(models.Model, AttrHelper):
    title = models.CharField(max_length=200, verbose_name=_('Title'))
    short_description = models.CharField(verbose_name=_('Short Description'),
        max_length=1024, blank=True)
    description = models.TextField(verbose_name=_('Description'))
    price = models.DecimalField(verbose_name=_('Price'), max_digits=12,
        decimal_places=2)
    shipping = models.DecimalField(verbose_name=_('Shipping Cost'),
        max_digits=12, decimal_places=2, default='0.0')
    attributes = generic.GenericRelation('tools.Attribute')

    tags = TaggableManager()

    related_products = models.ManyToManyField('self', blank=True,
        verbose_name=_('Related Products'))

    def __unicode__(self):
        return self.title
    def get_price(self, quantity):
        try:
            return self.pricebreak_set.filter(quantity__lte=quantity)[0].price
        except (PriceBreak.DoesNotExist, IndexError):
            return self.price
    def get_absolute_url(self):
        return reverse('product_detail', args=[self.pk])

def product_image_name(instance, filename):
    return 'images/products/%s/%s' % (instance.product.pk, filename,)

class ProductImage(models.Model):
    product = models.ForeignKey('Product', related_name='images')
    order = models.IntegerField(default=1)
    image = models.ImageField(upload_to=product_image_name)

    class Meta:
        ordering = ('-order',)

class ProductVariant(models.Model):
    product = models.ForeignKey('Product')
    sku = models.CharField(max_length=256, verbose_name=_("Order Code"))
    description = models.CharField(max_length=1024, blank=True,
        verbose_name=_('Description'))

    def __unicode__(self):
        return u'%s (%s)' % (self.product.short_description, self.description,)

    def get_absolute_url(self):
        return self.product.get_absolute_url()

class PriceBreak( models.Model ):
    product = models.ForeignKey('Product')
    quantity = models.PositiveIntegerField(verbose_name=_('Quantity'))
    price = models.DecimalField(max_digits=12, decimal_places=2,
        verbose_name=_('Price'))
    class Meta:
        ordering = ( 'quantity', )