Просмотр исходного кода

Clean up pep8 errors in oscar.apps.catalogue

master
David Winterbottom 13 лет назад
Родитель
Сommit
c8a780f60b

+ 170
- 96
oscar/apps/catalogue/abstract_models.py Просмотреть файл

@@ -12,12 +12,14 @@ from django.core.exceptions import ObjectDoesNotExist
12 12
 from treebeard.mp_tree import MP_Node
13 13
 
14 14
 from oscar.core.loading import get_class
15
-BrowsableProductManager = get_class('catalogue.managers', 'BrowsableProductManager')
15
+BrowsableProductManager = get_class('catalogue.managers',
16
+                                    'BrowsableProductManager')
16 17
 
17 18
 
18 19
 class AbstractProductClass(models.Model):
19 20
     """
20
-    Defines the options and attributes for a group of products, e.g. Books, DVDs and Toys.
21
+    Defines the options and attributes for a group of products, e.g. Books,
22
+    DVDs and Toys.
21 23
 
22 24
     Not necessarily equivalent to top-level categories but usually will be.
23 25
     """
@@ -26,15 +28,18 @@ class AbstractProductClass(models.Model):
26 28
 
27 29
     # Some product type don't require shipping (eg digital products) - we use
28 30
     # this field to take some shortcuts in the checkout.
29
-    requires_shipping = models.BooleanField(_("Requires shipping?"), default=True)
31
+    requires_shipping = models.BooleanField(_("Requires shipping?"),
32
+                                            default=True)
30 33
 
31
-    # Digital products generally don't require their stock levels to be tracked.
34
+    # Digital products generally don't require their stock levels to be
35
+    # tracked.
32 36
     track_stock = models.BooleanField(_("Track stock levels?"), default=True)
33 37
 
34 38
     # These are the options (set by the user when they add to basket) for this
35 39
     # item class.  For instance, a product class of "SMS message" would always
36 40
     # require a message to be specified before it could be bought.
37
-    options = models.ManyToManyField('catalogue.Option', blank=True, verbose_name=_("Options"))
41
+    options = models.ManyToManyField('catalogue.Option', blank=True,
42
+                                     verbose_name=_("Options"))
38 43
 
39 44
     class Meta:
40 45
         abstract = True
@@ -59,9 +64,12 @@ class AbstractCategory(MP_Node):
59 64
     """
60 65
     name = models.CharField(_('Name'), max_length=255, db_index=True)
61 66
     description = models.TextField(_('Description'), blank=True, null=True)
62
-    image = models.ImageField(_('Image'), upload_to='categories', blank=True, null=True)
63
-    slug = models.SlugField(_('Slug'), max_length=1024, db_index=True, editable=False)
64
-    full_name = models.CharField(_('Full Name'), max_length=1024, db_index=True, editable=False)
67
+    image = models.ImageField(_('Image'), upload_to='categories', blank=True,
68
+                              null=True)
69
+    slug = models.SlugField(_('Slug'), max_length=1024, db_index=True,
70
+                            editable=False)
71
+    full_name = models.CharField(_('Full Name'), max_length=1024,
72
+                                 db_index=True, editable=False)
65 73
 
66 74
     _slug_separator = '/'
67 75
     _full_name_separator = ' > '
@@ -74,9 +82,11 @@ class AbstractCategory(MP_Node):
74 82
             parent = self.get_parent()
75 83
             slug = slugify(self.name)
76 84
             if parent:
77
-                self.slug = '%s%s%s' % (parent.slug, self._slug_separator, slug)
85
+                self.slug = '%s%s%s' % (parent.slug,
86
+                                        self._slug_separator, slug)
78 87
                 self.full_name = '%s%s%s' % (parent.full_name,
79
-                                             self._full_name_separator, self.name)
88
+                                             self._full_name_separator,
89
+                                             self.name)
80 90
             else:
81 91
                 self.slug = slug
82 92
                 self.full_name = self.name
@@ -89,7 +99,9 @@ class AbstractCategory(MP_Node):
89 99
             pass
90 100
         else:
91 101
             if match.id != self.id:
92
-                raise ValidationError(_("A category with slug '%(slug)s' already exists") % {'slug': self.slug})
102
+                raise ValidationError(
103
+                    _("A category with slug '%(slug)s' already exists") % {
104
+                        'slug': self.slug})
93 105
         super(AbstractCategory, self).save(*args, **kwargs)
94 106
 
95 107
     def move(self, target, pos=None):
@@ -106,11 +118,12 @@ class AbstractCategory(MP_Node):
106 118
                 slug_parts = [parent.slug]
107 119
                 name_parts = [parent.full_name]
108 120
                 curr_depth = parent.depth
109
-            self.__class__.update_subtree_properties(list(subtree), slug_parts,
110
-                                                name_parts, curr_depth=curr_depth)
121
+            self.__class__.update_subtree_properties(
122
+                list(subtree), slug_parts, name_parts, curr_depth=curr_depth)
111 123
 
112 124
     @classmethod
113
-    def update_subtree_properties(cls, nodes, slug_parts, name_parts, curr_depth):
125
+    def update_subtree_properties(cls, nodes, slug_parts, name_parts,
126
+                                  curr_depth):
114 127
         """
115 128
         Update slugs and full_names of children in a subtree.
116 129
         Assumes nodes were originally in DFS order.
@@ -135,7 +148,8 @@ class AbstractCategory(MP_Node):
135 148
             name_parts = name_parts[:-1]
136 149
             curr_depth -= 1
137 150
 
138
-        cls.update_subtree_properties(nodes, slug_parts, name_parts, curr_depth)
151
+        cls.update_subtree_properties(
152
+            nodes, slug_parts, name_parts, curr_depth)
139 153
 
140 154
     def get_ancestors(self, include_self=True):
141 155
         ancestors = list(super(AbstractCategory, self).get_ancestors())
@@ -146,7 +160,7 @@ class AbstractCategory(MP_Node):
146 160
     @models.permalink
147 161
     def get_absolute_url(self):
148 162
         return ('catalogue:category', (), {
149
-                'category_slug': self.slug })
163
+                'category_slug': self.slug})
150 164
 
151 165
     class Meta:
152 166
         abstract = True
@@ -166,8 +180,10 @@ class AbstractProductCategory(models.Model):
166 180
     Joining model between products and categories.
167 181
     """
168 182
     product = models.ForeignKey('catalogue.Product', verbose_name=_("Product"))
169
-    category = models.ForeignKey('catalogue.Category', verbose_name=_("Category"))
170
-    is_canonical = models.BooleanField(_('Is Cannonical'), default=False, db_index=True)
183
+    category = models.ForeignKey('catalogue.Category',
184
+                                 verbose_name=_("Category"))
185
+    is_canonical = models.BooleanField(_('Is Cannonical'), default=False,
186
+                                       db_index=True)
171 187
 
172 188
     class Meta:
173 189
         abstract = True
@@ -181,7 +197,8 @@ class AbstractProductCategory(models.Model):
181 197
 
182 198
 class AbstractContributorRole(models.Model):
183 199
     """
184
-    A role that may be performed by a contributor to a product, eg Author, Actor, Director.
200
+    A role that may be performed by a contributor to a product, eg Author,
201
+    Actor, Director.
185 202
     """
186 203
     name = models.CharField(_('Name'), max_length=50)
187 204
     name_plural = models.CharField(_('Name Plural'), max_length=50)
@@ -203,7 +220,8 @@ class AbstractContributorRole(models.Model):
203 220
 
204 221
 class AbstractContributor(models.Model):
205 222
     """
206
-    Represents a person or business that has contributed to a product in some way. eg an author.
223
+    Represents a person or business that has contributed to a product in some
224
+    way. eg an author.
207 225
     """
208 226
     name = models.CharField(_("Name"), max_length=255)
209 227
     slug = models.SlugField(_("Slug"), max_length=255, unique=False)
@@ -216,7 +234,6 @@ class AbstractContributor(models.Model):
216 234
         verbose_name = _('Contributor')
217 235
         verbose_name_plural = _('Contributors')
218 236
 
219
-
220 237
     def save(self, *args, **kwargs):
221 238
         if not self.slug:
222 239
             self.slug = slugify(self.name)
@@ -225,8 +242,10 @@ class AbstractContributor(models.Model):
225 242
 
226 243
 class AbstractProductContributor(models.Model):
227 244
     product = models.ForeignKey('catalogue.Product', verbose_name=_("Product"))
228
-    contributor = models.ForeignKey('catalogue.Contributor', verbose_name=_("Contributor"))
229
-    role = models.ForeignKey('catalogue.ContributorRole', blank=True, null=True, verbose_name=_("Contributor Role"))
245
+    contributor = models.ForeignKey('catalogue.Contributor',
246
+                                    verbose_name=_("Contributor"))
247
+    role = models.ForeignKey('catalogue.ContributorRole', blank=True,
248
+                             null=True, verbose_name=_("Contributor Role"))
230 249
 
231 250
     def __unicode__(self):
232 251
         return '%s <- %s - %s' % (self.product, self.role, self.contributor)
@@ -241,47 +260,65 @@ class AbstractProduct(models.Model):
241 260
     """
242 261
     The base product object
243 262
     """
244
-    # If an item has no parent, then it is the "canonical" or abstract version of a product
245
-    # which essentially represents a set of products.  If a product has a parent
246
-    # then it is a specific version of a catalogue.
263
+    # If an item has no parent, then it is the "canonical" or abstract version
264
+    # of a product which essentially represents a set of products.  If a
265
+    # product has a parent then it is a specific version of a catalogue.
247 266
     #
248
-    # For example, a canonical product would have a title like "Green fleece" while its
249
-    # children would be "Green fleece - size L".
267
+    # For example, a canonical product would have a title like "Green fleece"
268
+    # while its children would be "Green fleece - size L".
250 269
 
251 270
     # Universal product code
252
-    upc = models.CharField(_("UPC"), max_length=64, blank=True, null=True, unique=True,
253
-        help_text=_("""Universal Product Code (UPC) is an identifier for a product which is
254
-                     not specific to a particular supplier.  Eg an ISBN for a book."""))
271
+    upc = models.CharField(_("UPC"), max_length=64, blank=True, null=True,
272
+                           unique=True,
273
+        help_text=_("Universal Product Code (UPC) is an identifier for "
274
+                    "a product which is not specific to a particular "
275
+                    " supplier. Eg an ISBN for a book."))
255 276
 
256 277
     # No canonical product should have a stock record as they cannot be bought.
257
-    parent = models.ForeignKey('self', null=True, blank=True, related_name='variants', verbose_name=_("Parent"),
258
-        help_text=_("""Only choose a parent product if this is a 'variant' of a canonical catalogue.  For example
259
-                     if this is a size 4 of a particular t-shirt.  Leave blank if this is a CANONICAL PRODUCT (ie
260
-                     there is only one version of this product)."""))
278
+    parent = models.ForeignKey('self', null=True, blank=True,
279
+                               related_name='variants',
280
+                               verbose_name=_("Parent"),
281
+        help_text=_("Only choose a parent product if this is a 'variant' of "
282
+                    "a canonical catalogue.  For example if this is a size "
283
+                    "4 of a particular t-shirt.  Leave blank if this is a "
284
+                    "CANONICAL PRODUCT (ie there is only one version of this "
285
+                    "product)."))
261 286
 
262 287
     # Title is mandatory for canonical products but optional for child products
263 288
     title = models.CharField(_('Title'), max_length=255, blank=True, null=True)
264 289
     slug = models.SlugField(_('Slug'), max_length=255, unique=False)
265 290
     description = models.TextField(_('Description'), blank=True, null=True)
266 291
 
267
-    # Use this field to indicate if the product is inactive or awaiting approval
268
-    status = models.CharField(_('Status'), max_length=128, blank=True, null=True, db_index=True)
269
-    product_class = models.ForeignKey('catalogue.ProductClass', verbose_name=_('Product Class'), null=True,
292
+    # Use this field to indicate if the product is inactive or awaiting
293
+    # approval
294
+    status = models.CharField(_('Status'), max_length=128, blank=True,
295
+                              null=True, db_index=True)
296
+    product_class = models.ForeignKey(
297
+        'catalogue.ProductClass', verbose_name=_('Product Class'), null=True,
270 298
         help_text=_("""Choose what type of product this is"""))
271
-    attributes = models.ManyToManyField('catalogue.ProductAttribute', through='ProductAttributeValue',
272
-        verbose_name=_("Attributes"), help_text=_("A product attribute is something that this product MUST have, "
273
-        "such as a size, as specified by its class"))
274
-    product_options = models.ManyToManyField('catalogue.Option', blank=True, verbose_name=_("Product Options"),
275
-        help_text=_("""Options are values that can be associated with a item when it is added to
276
-                     a customer's basket.  This could be something like a personalised message to be
277
-                     printed on a T-shirt."""))
278
-
279
-    related_products = models.ManyToManyField('catalogue.Product', related_name='relations', blank=True,
280
-        verbose_name=_("Related Products"), help_text=_("""Related items are things like different formats
281
-            of the same book.  Grouping them together allows better linking betwen products on the site."""))
299
+    attributes = models.ManyToManyField(
300
+        'catalogue.ProductAttribute',
301
+        through='ProductAttributeValue',
302
+        verbose_name=_("Attributes"),
303
+        help_text=_("A product attribute is something that this product MUST "
304
+                    "have, such as a size, as specified by its class"))
305
+    product_options = models.ManyToManyField(
306
+        'catalogue.Option', blank=True, verbose_name=_("Product Options"),
307
+        help_text=_("Options are values that can be associated with a item "
308
+                    "when it is added to a customer's basket.  This could be "
309
+                    "something like a personalised message to be printed on "
310
+                    "a T-shirt."))
311
+
312
+    related_products = models.ManyToManyField(
313
+        'catalogue.Product', related_name='relations', blank=True,
314
+        verbose_name=_("Related Products"),
315
+        help_text=_("Related items are things like different formats of the "
316
+                    "same book.  Grouping them together allows better linking "
317
+                    "betwen products on the site."))
282 318
 
283 319
     # Recommended products
284
-    recommended_products = models.ManyToManyField('catalogue.Product', through='ProductRecommendation', blank=True,
320
+    recommended_products = models.ManyToManyField(
321
+        'catalogue.Product', through='ProductRecommendation', blank=True,
285 322
         verbose_name=_("Recommended Products"))
286 323
 
287 324
     # Product score
@@ -290,9 +327,12 @@ class AbstractProduct(models.Model):
290 327
     date_created = models.DateTimeField(_("Date Created"), auto_now_add=True)
291 328
 
292 329
     # This field is used by Haystack to reindex search
293
-    date_updated = models.DateTimeField(_("Date Updated"), auto_now=True, db_index=True)
330
+    date_updated = models.DateTimeField(_("Date Updated"), auto_now=True,
331
+                                        db_index=True)
294 332
 
295
-    categories = models.ManyToManyField('catalogue.Category', through='ProductCategory', verbose_name=_("Categories"))
333
+    categories = models.ManyToManyField(
334
+        'catalogue.Category', through='ProductCategory',
335
+        verbose_name=_("Categories"))
296 336
 
297 337
     is_discountable = models.BooleanField(_("Is Discountable"), default=True)
298 338
 
@@ -305,7 +345,8 @@ class AbstractProduct(models.Model):
305 345
     def options(self):
306 346
         pclass = self.get_product_class()
307 347
         if pclass:
308
-            return list(chain(self.product_options.all(), self.get_product_class().options.all()))
348
+            return list(chain(self.product_options.all(),
349
+                              self.get_product_class().options.all()))
309 350
         return self.product_options.all()
310 351
 
311 352
     @property
@@ -317,7 +358,9 @@ class AbstractProduct(models.Model):
317 358
 
318 359
     @property
319 360
     def is_group(self):
320
-        u"""Return True if this is a top level product and has more than 0 variants"""
361
+        """
362
+        Test if this is a top level product and has more than 0 variants
363
+        """
321 364
         # use len() instead of count() in this specific instance
322 365
         # as variants are highly likely to be used after this
323 366
         # which reduces the amount of SQL queries required
@@ -325,7 +368,7 @@ class AbstractProduct(models.Model):
325 368
 
326 369
     @property
327 370
     def is_variant(self):
328
-        u"""Return True if a product is not a top level product"""
371
+        """Return True if a product is not a top level product"""
329 372
         return not self.is_top_level
330 373
 
331 374
     @property
@@ -382,7 +425,8 @@ class AbstractProduct(models.Model):
382 425
 
383 426
     def attribute_summary(self):
384 427
         u"""Return a string of all of a product's attributes"""
385
-        return ", ".join([attribute.__unicode__() for attribute in self.attributes.all()])
428
+        return ", ".join([
429
+            attribute.__unicode__() for attribute in self.attributes.all()])
386 430
 
387 431
     def get_title(self):
388 432
         """
@@ -410,8 +454,7 @@ class AbstractProduct(models.Model):
410 454
         return {
411 455
             'original': MissingProductImage(),
412 456
             'caption': '',
413
-            'is_missing': True
414
-        }
457
+            'is_missing': True}
415 458
 
416 459
     # Helpers
417 460
 
@@ -468,9 +511,11 @@ class ProductRecommendation(models.Model):
468 511
     """
469 512
     'Through' model for product recommendations
470 513
     """
471
-    primary = models.ForeignKey('catalogue.Product', related_name='primary_recommendations',
514
+    primary = models.ForeignKey(
515
+        'catalogue.Product', related_name='primary_recommendations',
472 516
         verbose_name=_("Primary Product"))
473
-    recommendation = models.ForeignKey('catalogue.Product', verbose_name=_("Recommended Product"))
517
+    recommendation = models.ForeignKey(
518
+        'catalogue.Product', verbose_name=_("Recommended Product"))
474 519
     ranking = models.PositiveSmallIntegerField(_('Ranking'), default=0)
475 520
 
476 521
     class Meta:
@@ -540,6 +585,10 @@ class ProductAttributesContainer(object):
540 585
 
541 586
 
542 587
 class AbstractProductAttribute(models.Model):
588
+    """
589
+    Defines an attribute for a product class. (For example, number_of_pages for
590
+    a 'book' class)
591
+    """
543 592
 
544 593
     TYPE_CHOICES = (
545 594
         ("text", _("Text")),
@@ -549,22 +598,26 @@ class AbstractProductAttribute(models.Model):
549 598
         ("richtext", _("Rich Text")),
550 599
         ("date", _("Date")),
551 600
         ("option", _("Option")),
552
-        ("entity", _("Entity"))
553
-    )
554
-
555
-    """
556
-    Defines an attribute for a product class. (For example, number_of_pages for a 'book' class)
557
-    """
558
-    product_class = models.ForeignKey('catalogue.ProductClass', related_name='attributes', blank=True, null=True,
559
-        verbose_name=_("Product Class"))
601
+        ("entity", _("Entity")))
602
+    product_class = models.ForeignKey(
603
+        'catalogue.ProductClass', related_name='attributes', blank=True,
604
+        null=True, verbose_name=_("Product Class"))
560 605
     name = models.CharField(_('Name'), max_length=128)
561
-    code = models.SlugField(_('Code'), max_length=128, validators=[RegexValidator(regex=r'^[a-zA-Z_][0-9a-zA-Z_]*$',
606
+    code = models.SlugField(
607
+        _('Code'), max_length=128,
608
+        validators=[RegexValidator(regex=r'^[a-zA-Z_][0-9a-zA-Z_]*$',
562 609
         message=_("Code must match ^[a-zA-Z_][0-9a-zA-Z_]*$"))])
563
-    type = models.CharField(choices=TYPE_CHOICES, default=TYPE_CHOICES[0][0], max_length=20, verbose_name=_("Type"))
564
-    option_group = models.ForeignKey('catalogue.AttributeOptionGroup', blank=True, null=True,
565
-        verbose_name=_("Option Group"), help_text=_('Select an option group if using type "Option"'))
566
-    entity_type = models.ForeignKey('catalogue.AttributeEntityType', blank=True, null=True,
567
-        verbose_name=_("Entity Type"), help_text=_('Select an entity type if using type "Entity"'))
610
+    type = models.CharField(
611
+        choices=TYPE_CHOICES, default=TYPE_CHOICES[0][0],
612
+        max_length=20, verbose_name=_("Type"))
613
+    option_group = models.ForeignKey(
614
+        'catalogue.AttributeOptionGroup', blank=True, null=True,
615
+        verbose_name=_("Option Group"),
616
+        help_text=_('Select an option group if using type "Option"'))
617
+    entity_type = models.ForeignKey(
618
+        'catalogue.AttributeEntityType', blank=True, null=True,
619
+        verbose_name=_("Entity Type"),
620
+        help_text=_('Select an entity type if using type "Entity"'))
568 621
     required = models.BooleanField(_('Required'), default=False)
569 622
 
570 623
     class Meta:
@@ -599,18 +652,22 @@ class AbstractProductAttribute(models.Model):
599 652
 
600 653
     def _validate_entity(self, value):
601 654
         if not isinstance(value, get_model('catalogue', 'AttributeEntity')):
602
-            raise ValidationError(_("Must be an AttributeEntity model object instance"))
655
+            raise ValidationError(
656
+                _("Must be an AttributeEntity model object instance"))
603 657
         if not value.pk:
604 658
             raise ValidationError(_("Model has not been saved yet"))
605 659
         if value.type != self.entity_type:
606
-            raise ValidationError(_("Entity must be of type %s" % self.entity_type.name))
660
+            raise ValidationError(
661
+                _("Entity must be of type %s" % self.entity_type.name))
607 662
 
608 663
     def _validate_option(self, value):
609 664
         if not isinstance(value, get_model('catalogue', 'AttributeOption')):
610
-            raise ValidationError(_("Must be an AttributeOption model object instance"))
665
+            raise ValidationError(
666
+                _("Must be an AttributeOption model object instance"))
611 667
         if not value.pk:
612 668
             raise ValidationError(_("AttributeOption has not been saved yet"))
613
-        valid_values = self.option_group.options.values_list('option', flat=True)
669
+        valid_values = self.option_group.options.values_list('option',
670
+                                                             flat=True)
614 671
         if value.option not in valid_values:
615 672
             raise ValidationError(_("%(enum)s is not a valid choice "
616 673
                                         "for %(attr)s") % \
@@ -642,7 +699,8 @@ class AbstractProductAttribute(models.Model):
642 699
         except get_model('catalogue', 'ProductAttributeValue').DoesNotExist:
643 700
             if value == None or value == '':
644 701
                 return
645
-            value_obj = get_model('catalogue', 'ProductAttributeValue').objects.create(product=product, attribute=self)
702
+            model = get_model('catalogue', 'ProductAttributeValue')
703
+            value_obj = model.objects.create(product=product, attribute=self)
646 704
         if value == None or value == '':
647 705
             value_obj.delete()
648 706
             return
@@ -658,7 +716,8 @@ class AbstractProductAttribute(models.Model):
658 716
         Check whether the passed value is valid for this attribute
659 717
         """
660 718
         if self.type == 'option':
661
-            valid_values = self.option_group.options.values_list('option', flat=True)
719
+            valid_values = self.option_group.options.values_list('option',
720
+                                                                 flat=True)
662 721
             return value in valid_values
663 722
         return True
664 723
 
@@ -671,17 +730,23 @@ class AbstractProductAttributeValue(models.Model):
671 730
 
672 731
     For example: number_of_pages = 295
673 732
     """
674
-    attribute = models.ForeignKey('catalogue.ProductAttribute', verbose_name=_("Attribute"))
675
-    product = models.ForeignKey('catalogue.Product', related_name='attribute_values', verbose_name=_("Product"))
676
-    value_text = models.CharField(_('Text'), max_length=255, blank=True, null=True)
733
+    attribute = models.ForeignKey('catalogue.ProductAttribute',
734
+                                  verbose_name=_("Attribute"))
735
+    product = models.ForeignKey(
736
+        'catalogue.Product', related_name='attribute_values',
737
+        verbose_name=_("Product"))
738
+    value_text = models.CharField(
739
+        _('Text'), max_length=255, blank=True, null=True)
677 740
     value_integer = models.IntegerField(_('Integer'), blank=True, null=True)
678 741
     value_boolean = models.BooleanField(_('Boolean'), blank=True)
679 742
     value_float = models.FloatField(_('Float'), blank=True, null=True)
680 743
     value_richtext = models.TextField(_('Richtext'), blank=True, null=True)
681 744
     value_date = models.DateField(_('Date'), blank=True, null=True)
682
-    value_option = models.ForeignKey('catalogue.AttributeOption', blank=True, null=True,
745
+    value_option = models.ForeignKey(
746
+        'catalogue.AttributeOption', blank=True, null=True,
683 747
         verbose_name=_("Value Option"))
684
-    value_entity = models.ForeignKey('catalogue.AttributeEntity', blank=True, null=True,
748
+    value_entity = models.ForeignKey(
749
+        'catalogue.AttributeEntity', blank=True, null=True,
685 750
         verbose_name=_("Value Entity"))
686 751
 
687 752
     def _get_value(self):
@@ -690,7 +755,8 @@ class AbstractProductAttributeValue(models.Model):
690 755
     def _set_value(self, new_value):
691 756
         if self.attribute.type == 'option' and isinstance(new_value, str):
692 757
             # Need to look up instance of AttributeOption
693
-            new_value = self.attribute.option_group.options.get(option=new_value)
758
+            new_value = self.attribute.option_group.options.get(
759
+                option=new_value)
694 760
         setattr(self, 'value_%s' % self.attribute.type, new_value)
695 761
 
696 762
     value = property(_get_value, _set_value)
@@ -726,7 +792,9 @@ class AbstractAttributeOption(models.Model):
726 792
     Provides an option within an option group for an attribute type
727 793
     Examples: In a Language group, English, Greek, French
728 794
     """
729
-    group = models.ForeignKey('catalogue.AttributeOptionGroup', related_name='options', verbose_name=_("Group"))
795
+    group = models.ForeignKey(
796
+        'catalogue.AttributeOptionGroup', related_name='options',
797
+        verbose_name=_("Group"))
730 798
     option = models.CharField(_('Option'), max_length=255)
731 799
 
732 800
     def __unicode__(self):
@@ -743,8 +811,11 @@ class AbstractAttributeEntity(models.Model):
743 811
     Provides an attribute type to enable relationships with other models
744 812
     """
745 813
     name = models.CharField(_("Name"), max_length=255)
746
-    slug = models.SlugField(_("Slug"), max_length=255, unique=False, blank=True)
747
-    type = models.ForeignKey('catalogue.AttributeEntityType', related_name='entities', verbose_name=_("Type"))
814
+    slug = models.SlugField(
815
+        _("Slug"), max_length=255, unique=False, blank=True)
816
+    type = models.ForeignKey(
817
+        'catalogue.AttributeEntityType', related_name='entities',
818
+        verbose_name=_("Type"))
748 819
 
749 820
     def __unicode__(self):
750 821
         return self.name
@@ -765,7 +836,8 @@ class AbstractAttributeEntityType(models.Model):
765 836
     Provides the name of the model involved in an entity relationship
766 837
     """
767 838
     name = models.CharField(_("Name"), max_length=255)
768
-    slug = models.SlugField(_("Slug"), max_length=255, unique=False, blank=True)
839
+    slug = models.SlugField(
840
+        _("Slug"), max_length=255, unique=False, blank=True)
769 841
 
770 842
     def __unicode__(self):
771 843
         return self.name
@@ -786,8 +858,8 @@ class AbstractOption(models.Model):
786 858
     An option that can be selected for a particular item when the product
787 859
     is added to the basket.
788 860
 
789
-    For example,  a list ID for an SMS message send, or a personalised message to
790
-    print on a T-shirt.
861
+    For example,  a list ID for an SMS message send, or a personalised message
862
+    to print on a T-shirt.
791 863
 
792 864
     This is not the same as an 'attribute' as options do not have a fixed value
793 865
     for a particular item.  Instead, option need to be specified by a customer
@@ -832,9 +904,12 @@ class AbstractProductImage(models.Model):
832 904
     """
833 905
     An image of a product
834 906
     """
835
-    product = models.ForeignKey('catalogue.Product', related_name='images', verbose_name=_("Product"))
836
-    original = models.ImageField(_("Original"), upload_to=settings.OSCAR_IMAGE_FOLDER)
837
-    caption = models.CharField(_("Caption"), max_length=200, blank=True, null=True)
907
+    product = models.ForeignKey(
908
+        'catalogue.Product', related_name='images', verbose_name=_("Product"))
909
+    original = models.ImageField(
910
+        _("Original"), upload_to=settings.OSCAR_IMAGE_FOLDER)
911
+    caption = models.CharField(
912
+        _("Caption"), max_length=200, blank=True, null=True)
838 913
 
839 914
     # Use display_order to determine which is the "primary" image
840 915
     display_order = models.PositiveIntegerField(_("Display Order"), default=0,
@@ -873,4 +948,3 @@ class AbstractProductImage(models.Model):
873 948
     @property
874 949
     def thumbnail_url(self):
875 950
         return self.resized_image_url()
876
-

+ 23
- 9
oscar/apps/catalogue/admin.py Просмотреть файл

@@ -20,43 +20,57 @@ ProductCategory = get_model('catalogue', 'ProductCategory')
20 20
 class AttributeInline(admin.TabularInline):
21 21
     model = ProductAttributeValue
22 22
 
23
+
23 24
 class ProductRecommendationInline(admin.TabularInline):
24 25
     model = ProductRecommendation
25 26
     fk_name = 'primary'
26
-    
27
+
28
+
27 29
 class CategoryInline(admin.TabularInline):
28 30
     model = ProductCategory
29 31
     extra = 1
30 32
 
33
+
31 34
 class ProductClassAdmin(admin.ModelAdmin):
32 35
     prepopulated_fields = {"slug": ("name",)}
33
-    
36
+
37
+
34 38
 class ProductAdmin(admin.ModelAdmin):
35
-    list_display = ('get_title', 'upc', 'get_product_class', 'is_top_level', 'is_group', 'is_variant', 'attribute_summary', 'date_created')
39
+    list_display = ('get_title', 'upc', 'get_product_class', 'is_top_level',
40
+                    'is_group', 'is_variant', 'attribute_summary',
41
+                    'date_created')
36 42
     prepopulated_fields = {"slug": ("title",)}
37 43
     inlines = [AttributeInline, CategoryInline, ProductRecommendationInline]
38
-    
44
+
45
+
39 46
 class ProductAttributeAdmin(admin.ModelAdmin):
40 47
     prepopulated_fields = {"code": ("name", )}
41
-    
48
+
49
+
42 50
 class OptionAdmin(admin.ModelAdmin):
43 51
     exclude = ['code']
44
-    
52
+
53
+
45 54
 class ProductAttributeValueAdmin(admin.ModelAdmin):
46 55
     list_display = ('product', 'attribute', 'value')
47 56
 
57
+
48 58
 class AttributeOptionInline(admin.TabularInline):
49 59
     model = AttributeOption
50
-    
60
+
61
+
51 62
 class AttributeOptionGroupAdmin(admin.ModelAdmin):
52 63
     inlines = [AttributeOptionInline, ]
53
-        
64
+
65
+
54 66
 class AttributeEntityAdmin(admin.ModelAdmin):
55 67
     list_display = ('name', )
56
-                 
68
+
69
+
57 70
 class CategoryAdmin(TreeAdmin):
58 71
     pass
59 72
 
73
+
60 74
 admin.site.register(ProductClass, ProductClassAdmin)
61 75
 admin.site.register(Product, ProductAdmin)
62 76
 admin.site.register(ProductAttribute, ProductAttributeAdmin)

+ 5
- 6
oscar/apps/catalogue/app.py Просмотреть файл

@@ -1,15 +1,15 @@
1 1
 from django.conf.urls import patterns, url, include
2 2
 
3 3
 from oscar.core.application import Application
4
-from oscar.apps.catalogue.views import ProductDetailView, ProductListView, ProductCategoryView
4
+from oscar.apps.catalogue import views
5 5
 from oscar.apps.catalogue.reviews.app import application as reviews_app
6 6
 
7 7
 
8 8
 class BaseCatalogueApplication(Application):
9 9
     name = 'catalogue'
10
-    detail_view = ProductDetailView
11
-    index_view = ProductListView
12
-    category_view = ProductCategoryView
10
+    detail_view = views.ProductDetailView
11
+    index_view = views.ProductListView
12
+    category_view = views.ProductCategoryView
13 13
 
14 14
     def get_urls(self):
15 15
         urlpatterns = super(BaseCatalogueApplication, self).get_urls()
@@ -18,8 +18,7 @@ class BaseCatalogueApplication(Application):
18 18
             url(r'^(?P<product_slug>[\w-]*)_(?P<pk>\d+)/$',
19 19
                 self.detail_view.as_view(), name='detail'),
20 20
             url(r'^(?P<category_slug>[\w-]+(/[\w-]+)*)/$',
21
-                self.category_view.as_view(), name='category')
22
-        )
21
+                self.category_view.as_view(), name='category'))
23 22
         return self.post_process_urls(urlpatterns)
24 23
 
25 24
 

+ 1
- 1
oscar/apps/catalogue/exceptions.py Просмотреть файл

@@ -7,4 +7,4 @@ class IdenticalImageError(Exception):
7 7
 
8 8
 
9 9
 class InvalidImageArchive(Exception):
10
-    pass    
10
+    pass

+ 2
- 1
oscar/apps/catalogue/managers.py Просмотреть файл

@@ -3,4 +3,5 @@ from django.db import models
3 3
 
4 4
 class BrowsableProductManager(models.Manager):
5 5
     def get_query_set(self):
6
-        return super(BrowsableProductManager, self).get_query_set().filter(parent=None)
6
+        return super(BrowsableProductManager, self).get_query_set().filter(
7
+            parent=None)

+ 2
- 3
oscar/apps/catalogue/models.py Просмотреть файл

@@ -30,8 +30,8 @@ class Contributor(AbstractContributor):
30 30
 
31 31
 class ProductContributor(AbstractProductContributor):
32 32
     pass
33
-    
34
-    
33
+
34
+
35 35
 class ProductAttribute(AbstractProductAttribute):
36 36
     pass
37 37
 
@@ -62,4 +62,3 @@ class Option(AbstractOption):
62 62
 
63 63
 class ProductImage(AbstractProductImage):
64 64
     pass
65
-

+ 2
- 1
oscar/apps/catalogue/signals.py Просмотреть файл

@@ -1,6 +1,7 @@
1 1
 import django.dispatch
2 2
 
3
-product_viewed = django.dispatch.Signal(providing_args=["product", "user", "request", "response"])
3
+product_viewed = django.dispatch.Signal(
4
+    providing_args=["product", "user", "request", "response"])
4 5
 
5 6
 # This needs to be moved into the search app when it is refactored
6 7
 product_search = django.dispatch.Signal(providing_args=["query", '"user'])

+ 3
- 3
oscar/apps/catalogue/utils.py Просмотреть файл

@@ -11,7 +11,8 @@ from django.core.exceptions import FieldError
11 11
 from django.db.models import get_model
12 12
 from django.utils.translation import ugettext_lazy as _
13 13
 
14
-from oscar.apps.catalogue.exceptions import ImageImportError, IdenticalImageError, InvalidImageArchive
14
+from oscar.apps.catalogue.exceptions import (
15
+    ImageImportError, IdenticalImageError, InvalidImageArchive)
15 16
 
16 17
 Category = get_model('catalogue', 'category')
17 18
 Product = get_model('catalogue', 'product')
@@ -30,8 +31,7 @@ class Importer(object):
30 31
         stats = {
31 32
             'num_processed': 0,
32 33
             'num_skipped': 0,
33
-            'num_invalid': 0
34
-        }
34
+            'num_invalid': 0}
35 35
         image_dir, filenames = self._get_image_files(dirname)
36 36
         if image_dir:
37 37
             for filename in filenames:

Загрузка…
Отмена
Сохранить