Adding additional product details

The application we've built so far is actually quite powerful, but in this section we'll take our design to another level of flexibility. Products, as they currently exist, have a limited amount of information that can be stored about them. These are the six fields discussed earlier: name, description, photo, manufacturer, and price. These attributes will be common to all products in our catalog. There may be more attributes appropriate for this model, for example, size or weight, but we have left those unimplemented for now.

A lot of product information, though, is specific to only certain products or certain kinds of products. Capturing this information requires a more sophisticated design. Our goal, as always, will be to keep things as simple as possible and to take advantage of the built-in functionality that Django offers.

In an ideal world, we would like to allow an unlimited number of fields to capture all the potential descriptive information for any product. Unfortunately, this is not possible using the relational database systems that drive the majority of web-based applications. Instead, we must create a set of models with relationships in such a way that it effectively gives us what we need.

Database administrators are constantly implementing designs like this. But when it comes to frameworks like Django, with their own ORM systems, there's a great temptation to try and create fancy models with ManyToManyFields all over the place, which can capture everything and do so very cleverly. This is almost always more complex than is necessary, but because Django makes it so easy, it becomes a great temptation.

In our case we will build a fairly simple pair of models that allow us to store arbitrary information for any product. These models are the ProductDetail and ProductAttribute and they are as follows:

class ProductDetail(models.Model):
    '''
    The ``ProductDetail`` model represents information unique to a specific product. This is a generic design that can be used to extend the information contained in the ``Product`` model with specific, extra details.
    '''
    product = models.ForeignKey('Product',
                                 related_name='details')
    attribute = models.ForeignKey('ProductAttribute')        
    value = models.CharField(max_length=500)        
    description = models.TextField(blank=True)
       
    def __unicode__(self):
        return u'%s: %s - %s' % (self.product, 
                                 self.attribute,
                                 self.value)

class ProductAttribute(models.Model):
    '''
    The ``ProductAttribute`` model represents a class of feature found 
    across a set of products. It does not store any data values related to the attribute, but only describes what kind of a product feature we are trying to capture. Possible attributes include things such as materials, colors, sizes, and many, many more.
    '''
    name = models.CharField(max_length=300)
    description = models.TextField(blank=True)

    def __unicode__(self):
        return u'%s' % self.name

As noted in the model docstrings, the ProductDetail design relates a kind of attribute to a specific product and stores the attribute value, as well as an optional extended description of the value.

Suppose our friends at CranStore.com offer a new selection of premium cranberries, created from special seedlings developed over years of careful breeding. Each variety of these premium cranberries features different characteristics. For example, some are extremely tart, while others are extra sweet, and so on.

Adding additional product details

To capture this additional information, we created a Tartness ProductAttribute and used it to add ProductDetail instances for the relevant product. You can see the end-result of adding this attribute in the previous screenshot.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.5.86