|
|
@@ -58,19 +58,33 @@ class AbstractItem(models.Model):
|
|
58
|
58
|
upc = models.CharField(_("UPC"), max_length=64, blank=True, null=True,
|
|
59
|
59
|
help_text="""Universal Product Code (UPC) is an identifier for a product which is
|
|
60
|
60
|
not specific to a particular supplier. Eg an ISBN for a book.""")
|
|
|
61
|
+
|
|
61
|
62
|
# No canonical product should have a stock record as they cannot be bought.
|
|
62
|
63
|
parent = models.ForeignKey('self', null=True, blank=True, related_name='variants',
|
|
63
|
64
|
help_text="""Only choose a parent product if this is a 'variant' of a canonical product. For example
|
|
64
|
65
|
if this is a size 4 of a particular t-shirt. Leave blank if this is a CANONICAL PRODUCT (ie
|
|
65
|
66
|
there is only one version of this product).""")
|
|
|
67
|
+
|
|
66
|
68
|
# Title is mandatory for canonical products but optional for child products
|
|
67
|
69
|
title = models.CharField(_('Title'), max_length=255, blank=True, null=True)
|
|
68
|
70
|
slug = models.SlugField(max_length=255, unique=False)
|
|
69
|
71
|
description = models.TextField(_('Description'), blank=True, null=True)
|
|
70
|
72
|
item_class = models.ForeignKey('product.ItemClass', verbose_name=_('item class'), null=True,
|
|
71
|
73
|
help_text="""Choose what type of product this is""")
|
|
72
|
|
- attribute_types = models.ManyToManyField('product.AttributeType', through='ItemAttributeValue')
|
|
73
|
|
- item_options = models.ManyToManyField('product.Option', blank=True)
|
|
|
74
|
+ attribute_types = models.ManyToManyField('product.AttributeType', through='ItemAttributeValue',
|
|
|
75
|
+ help_text="""An attribute type is something that this product MUST have, such as a size""")
|
|
|
76
|
+ item_options = models.ManyToManyField('product.Option', blank=True,
|
|
|
77
|
+ help_text="""Options are values that can be associated with a item when it is added to
|
|
|
78
|
+ a customer's basket. This could be something like a personalised message to be
|
|
|
79
|
+ printed on a T-shirt.<br/>""")
|
|
|
80
|
+
|
|
|
81
|
+ related_items = models.ManyToManyField('product.Item', related_name='relations', blank=True, help_text="""Related
|
|
|
82
|
+ items are things like different formats of the same book. Grouping them together allows
|
|
|
83
|
+ better linking betwen products on the site.<br/>""")
|
|
|
84
|
+
|
|
|
85
|
+ # Recommended products
|
|
|
86
|
+ recommended_items = models.ManyToManyField('product.Item', through='ProductRecommendation', blank=True)
|
|
|
87
|
+
|
|
74
|
88
|
date_created = models.DateTimeField(auto_now_add=True)
|
|
75
|
89
|
date_updated = models.DateTimeField(auto_now=True, null=True, default=None)
|
|
76
|
90
|
|
|
|
@@ -174,6 +188,16 @@ class AbstractItem(models.Model):
|
|
174
|
188
|
super(AbstractItem, self).save(*args, **kwargs)
|
|
175
|
189
|
|
|
176
|
190
|
|
|
|
191
|
+class ProductRecommendation(models.Model):
|
|
|
192
|
+ u"""
|
|
|
193
|
+ 'Through' model for product recommendations
|
|
|
194
|
+ """
|
|
|
195
|
+
|
|
|
196
|
+ primary = models.ForeignKey('product.Item', related_name='primary_recommendations')
|
|
|
197
|
+ recommendation = models.ForeignKey('product.Item')
|
|
|
198
|
+ ranking = models.PositiveSmallIntegerField(default=0)
|
|
|
199
|
+
|
|
|
200
|
+
|
|
177
|
201
|
class AbstractAttributeType(models.Model):
|
|
178
|
202
|
u"""Defines an attribute. (Eg. size)"""
|
|
179
|
203
|
name = models.CharField(_('name'), max_length=128)
|
|
|
@@ -227,8 +251,12 @@ class AbstractItemAttributeValue(models.Model):
|
|
227
|
251
|
class AbstractOption(models.Model):
|
|
228
|
252
|
u"""
|
|
229
|
253
|
An option that can be selected for a particular item when the product
|
|
230
|
|
- is added to the basket. Eg a message for a SMS message. This is not
|
|
231
|
|
- the same as an attribute as options do not have a fixed value for
|
|
|
254
|
+ is added to the basket.
|
|
|
255
|
+
|
|
|
256
|
+ Eg a list ID for an SMS message send, or a personalised message to
|
|
|
257
|
+ print on a T-shirt.
|
|
|
258
|
+
|
|
|
259
|
+ This is not the same as an attribute as options do not have a fixed value for
|
|
232
|
260
|
a particular item - options, they need to be specified by the customer.
|
|
233
|
261
|
"""
|
|
234
|
262
|
name = models.CharField(_('name'), max_length=128)
|
|
|
@@ -251,4 +279,6 @@ class AbstractOption(models.Model):
|
|
251
|
279
|
if not self.code:
|
|
252
|
280
|
self.code = _convert_to_underscores(self.name)
|
|
253
|
281
|
super(AbstractOption, self).save(*args, **kwargs)
|
|
|
282
|
+
|
|
|
283
|
+
|
|
254
|
284
|
|