Browse Source

Minor tweaks to i18n changes

master
David Winterbottom 13 years ago
parent
commit
e7db57e7bc

+ 3
- 4
oscar/apps/address/abstract_models.py View File

@@ -45,7 +45,6 @@ class AbstractAddress(models.Model):
45 45
         verbose_name = _('Address')
46 46
         verbose_name_plural = _('Addresses')
47 47
 
48
-
49 48
     def save(self, *args, **kwargs):
50 49
         self._clean_fields()
51 50
         self._update_search_text()
@@ -144,7 +143,7 @@ class AbstractCountry(models.Model):
144 143
         
145 144
 
146 145
 class AbstractShippingAddress(AbstractAddress):
147
-    u"""
146
+    """
148 147
     Shipping address.
149 148
     
150 149
     A shipping address should not be edited once the order has been placed - 
@@ -158,8 +157,8 @@ class AbstractShippingAddress(AbstractAddress):
158 157
     
159 158
     class Meta:
160 159
         abstract = True
161
-        verbose_name = _("shipping address")
162
-        verbose_name_plural = _("shipping addresses")
160
+        verbose_name = _("Shipping address")
161
+        verbose_name_plural = _("Shipping addresses")
163 162
 
164 163
     @property    
165 164
     def order(self):

+ 7
- 5
oscar/apps/analytics/abstract_models.py View File

@@ -5,7 +5,7 @@ from django.utils.translation import ugettext as _
5 5
 
6 6
 
7 7
 class AbstractProductRecord(models.Model):
8
-    u"""
8
+    """
9 9
     A record of a how popular a product is.
10 10
     
11 11
     This used be auto-merchandising to display the most popular
@@ -25,8 +25,8 @@ class AbstractProductRecord(models.Model):
25 25
     class Meta:
26 26
         abstract = True
27 27
         ordering = ['-num_purchases']
28
-        verbose_name = _('Product Record')
29
-        verbose_name_plural = _('Product Records')
28
+        verbose_name = _('Product record')
29
+        verbose_name_plural = _('Product records')
30 30
 
31 31
 
32 32
     def __unicode__(self):
@@ -34,7 +34,7 @@ class AbstractProductRecord(models.Model):
34 34
         
35 35
 
36 36
 class AbstractUserRecord(models.Model):
37
-    u"""
37
+    """
38 38
     A record of a user's activity.
39 39
     """
40 40
     
@@ -86,4 +86,6 @@ class AbstractUserSearch(models.Model):
86 86
         
87 87
     def __unicode__(self):
88 88
         return _("%(user)s searched for '%(query)s'") % {
89
-            'user':self.user, 'query':self.query}
89
+            'user': self.user,
90
+            'query': self.query
91
+        }

+ 4
- 0
oscar/apps/analytics/admin.py View File

@@ -1,15 +1,19 @@
1 1
 from django.contrib import admin
2 2
 from django.db.models import get_model
3 3
 
4
+
4 5
 class ProductRecordAdmin(admin.ModelAdmin):
5 6
     list_display = ('product', 'num_views', 'num_basket_additions', 'num_purchases')
6 7
     
8
+
7 9
 class UserProductViewAdmin(admin.ModelAdmin):
8 10
     list_display = ('user', 'product', 'date_created')
9 11
 
12
+
10 13
 class UserRecordAdmin(admin.ModelAdmin):
11 14
     list_display = ('user', 'num_product_views', 'num_basket_additions', 'num_orders', 'total_spent', 'date_last_order')
12 15
 
16
+
13 17
 admin.site.register(get_model('analytics', 'productrecord'), ProductRecordAdmin)
14 18
 admin.site.register(get_model('analytics', 'userrecord'), UserRecordAdmin)
15 19
 admin.site.register(get_model('analytics', 'usersearch'))

+ 2
- 4
oscar/apps/analytics/reports.py View File

@@ -1,7 +1,6 @@
1 1
 import csv
2 2
 
3 3
 from django.db.models import get_model
4
-from django.template.defaultfilters import date
5 4
 from django.utils.translation import ugettext_lazy as _
6 5
 
7 6
 from oscar.core.loading import get_class
@@ -42,8 +41,8 @@ class ProductReportGenerator(ReportGenerator):
42 41
     description = _('Product analytics')
43 42
 
44 43
     formatters = {
45
-      'CSV_formatter': ProductReportCSVFormatter,
46
-      'HTML_formatter': ProductReportHTMLFormatter
44
+        'CSV_formatter': ProductReportCSVFormatter,
45
+        'HTML_formatter': ProductReportHTMLFormatter
47 46
     }
48 47
 
49 48
     def generate(self):
@@ -89,7 +88,6 @@ class UserReportHTMLFormatter(ReportHTMLFormatter):
89 88
 
90 89
 
91 90
 class UserReportGenerator(ReportGenerator):
92
-
93 91
     code = 'user_analytics'
94 92
     description = _('User analytics')
95 93
 

+ 1
- 1
oscar/apps/analytics/scores.py View File

@@ -32,7 +32,7 @@ class Calculator(object):
32 32
         sql = '''UPDATE `%(table)s` 
33 33
                  SET score = %(weighted_total)s / %(total_weight)s''' % ctx
34 34
 
35
-        self.logger.debug(sql)         
35
+        self.logger.debug(sql)
36 36
         self.cursor.execute(sql)
37 37
         transaction.commit_unless_managed()
38 38
         

+ 11
- 10
oscar/apps/basket/abstract_models.py View File

@@ -386,9 +386,8 @@ class AbstractLine(models.Model):
386 386
     class Meta:
387 387
         abstract = True
388 388
         unique_together = ("basket", "line_reference")
389
-        verbose_name = _('Pozycja koszyka')
390
-        verbose_name_plural = _('Pozycje koszyka')
391
-
389
+        verbose_name = _('Basket line')
390
+        verbose_name_plural = _('Basket lines')
392 391
 
393 392
     def __unicode__(self):
394 393
         return _(u"%(basket)s, Product '%(product)s', quantity %(quantity)d") % {
@@ -552,24 +551,26 @@ class AbstractLine(models.Model):
552 551
             msg = u"The price of '%(product)s' has increased from %(old_price)s " \
553 552
                   u"to %(new_price)s since you added it to your basket"
554 553
             return _(msg) % {'product': self.product.get_title(),
555
-                            'old_price': currency(self.price_incl_tax),
556
-                            'new_price': currency(current_price_incl_tax)}
554
+                             'old_price': currency(self.price_incl_tax),
555
+                             'new_price': currency(current_price_incl_tax)}
557 556
         if current_price_incl_tax < self.price_incl_tax:
558 557
             msg = u"The price of '%(product)s' has decreased from %(old_price)s " \
559 558
                   u"to %(new_price)s since you added it to your basket"
560 559
             return _(msg) % {'product': self.product.get_title(),
561
-                            'old_price': currency(self.price_incl_tax),
562
-                            'new_price': currency(current_price_incl_tax)}
560
+                             'old_price': currency(self.price_incl_tax),
561
+                             'new_price': currency(current_price_incl_tax)}
563 562
 
564 563
 
565 564
 class AbstractLineAttribute(models.Model):
566
-    """An attribute of a basket line"""
565
+    """
566
+    An attribute of a basket line
567
+    """
567 568
     line = models.ForeignKey('basket.Line', related_name='attributes')
568 569
     option = models.ForeignKey('catalogue.Option')
569 570
     value = models.CharField(_("Value"), max_length=255)
570 571
 
571 572
     class Meta:
572 573
         abstract = True
573
-        verbose_name = _('Atrybut pozycji')
574
-        verbose_name_plural = _('Atrybuty pozycji')
574
+        verbose_name = _('Line attribute')
575
+        verbose_name_plural = _('Line attributes')
575 576
 

+ 4
- 3
oscar/apps/basket/app.py View File

@@ -15,13 +15,14 @@ class BasketApplication(Application):
15 15
     remove_voucher_view = VoucherRemoveView
16 16
 
17 17
     def get_urls(self):
18
-        urlpatterns = patterns('',                   
18
+        urlpatterns = patterns('',
19 19
             url(r'^$', self.summary_view.as_view(), name='summary'),
20
-            url(r'^add/$', self.add_view.as_view(), name='add'),    
20
+            url(r'^add/$', self.add_view.as_view(), name='add'),
21 21
             url(r'^vouchers/add/$', self.add_voucher_view.as_view(), name='vouchers-add'),
22
-            url(r'^vouchers/(?P<pk>\d+)/remove/$', self.remove_voucher_view.as_view(), name='vouchers-remove'),     
22
+            url(r'^vouchers/(?P<pk>\d+)/remove/$', self.remove_voucher_view.as_view(), name='vouchers-remove'),
23 23
             url(r'^saved/$', login_required(self.saved_view.as_view()), name='saved'),
24 24
         )
25 25
         return self.post_process_urls(urlpatterns)
26 26
 
27
+
27 28
 application = BasketApplication()

+ 0
- 1
oscar/apps/basket/forms.py View File

@@ -195,4 +195,3 @@ class AddToBasketForm(forms.Form):
195 195
 
196 196
 class SimpleAddToBasketForm(AddToBasketForm):
197 197
     quantity = forms.IntegerField(initial=1, min_value=1, widget=forms.HiddenInput, label=_('Quantity'))
198
-

+ 6
- 6
oscar/apps/basket/managers.py View File

@@ -4,23 +4,23 @@ from django.db import models
4 4
 class OpenBasketManager(models.Manager):
5 5
     u"""For searching/creating OPEN baskets only."""
6 6
     status_filter = "Open"
7
-    
7
+
8 8
     def get_query_set(self):
9 9
         return super(OpenBasketManager, self).get_query_set().filter(status=self.status_filter)
10
-    
10
+
11 11
     def get_or_create(self, **kwargs):
12 12
         return self.get_query_set().get_or_create(status=self.status_filter, **kwargs)
13 13
 
14
-    
14
+
15 15
 class SavedBasketManager(models.Manager):
16 16
     u"""For searching/creating SAVED baskets only."""
17 17
     status_filter = "Saved"
18
-    
18
+
19 19
     def get_query_set(self):
20 20
         return super(SavedBasketManager, self).get_query_set().filter(status=self.status_filter)
21
-    
21
+
22 22
     def create(self, **kwargs):
23 23
         return self.get_query_set().create(status=self.status_filter, **kwargs)
24
-    
24
+
25 25
     def get_or_create(self, **kwargs):
26 26
         return self.get_query_set().get_or_create(status=self.status_filter, **kwargs)

+ 21
- 21
oscar/apps/basket/middleware.py View File

@@ -11,18 +11,18 @@ Basket = get_model('basket', 'basket')
11 11
 
12 12
 
13 13
 class BasketMiddleware(object):
14
-    
14
+
15 15
     def process_request(self, request):
16 16
         self.cookies_to_delete = []
17 17
         basket = self.get_basket(request)
18
-        self.apply_offers_to_basket(request, basket)   
18
+        self.apply_offers_to_basket(request, basket)
19 19
         request.basket = basket
20
-    
21
-    def get_basket(self, request):  
20
+
21
+    def get_basket(self, request):
22 22
         manager = Basket.open
23
-        cookie_basket = self.get_cookie_basket(settings.OSCAR_BASKET_COOKIE_OPEN, 
23
+        cookie_basket = self.get_cookie_basket(settings.OSCAR_BASKET_COOKIE_OPEN,
24 24
                                                request, manager)
25
-        
25
+
26 26
         if request.user.is_authenticated():
27 27
             # Signed-in user: if they have a cookie basket too, it means
28 28
             # that they have just signed in and we need to merge their cookie
@@ -36,7 +36,7 @@ class BasketMiddleware(object):
36 36
                 basket = old_baskets[0]
37 37
                 for other_basket in old_baskets[1:]:
38 38
                     self.merge_baskets(basket, other_basket)
39
-                
39
+
40 40
             if cookie_basket:
41 41
                 self.merge_baskets(basket, cookie_basket)
42 42
                 self.cookies_to_delete.append(settings.OSCAR_BASKET_COOKIE_OPEN)
@@ -47,45 +47,45 @@ class BasketMiddleware(object):
47 47
             # Anonymous user with no basket - we don't save the basket until
48 48
             # we need to.
49 49
             basket = Basket()
50
-        return basket 
51
-            
50
+        return basket
51
+
52 52
     def merge_baskets(self, master, slave):
53 53
         """
54 54
         Merge one basket into another.
55
-        
55
+
56 56
         This is its own method to allow it to be overridden
57 57
         """
58 58
         master.merge(slave, add_quantities=False)
59
-        
59
+
60 60
     def process_response(self, request, response):
61 61
         # Delete any surplus cookies
62 62
         if hasattr(self, 'cookies_to_delete'):
63 63
             for cookie_key in self.cookies_to_delete:
64 64
                 response.delete_cookie(cookie_key)
65
-            
65
+
66 66
         # If a basket has had products added to it, but the user is anonymous
67 67
         # then we need to assign it to a cookie
68 68
         if hasattr(request, 'basket') and request.basket.id > 0 \
69 69
             and not request.user.is_authenticated() \
70 70
             and settings.OSCAR_BASKET_COOKIE_OPEN not in request.COOKIES:
71 71
             cookie = "%s_%s" % (request.basket.id, self.get_basket_hash(request.basket.id))
72
-            response.set_cookie(settings.OSCAR_BASKET_COOKIE_OPEN, 
73
-                                cookie, 
74
-                                max_age=settings.OSCAR_BASKET_COOKIE_LIFETIME, 
72
+            response.set_cookie(settings.OSCAR_BASKET_COOKIE_OPEN,
73
+                                cookie,
74
+                                max_age=settings.OSCAR_BASKET_COOKIE_LIFETIME,
75 75
                                 httponly=True)
76 76
         return response
77
-    
77
+
78 78
     def process_template_response(self, request, response):
79 79
         if hasattr(response, 'context_data'):
80 80
             if response.context_data is None:
81 81
                 response.context_data = {}
82 82
             response.context_data['basket'] = request.basket
83 83
         return response
84
-    
84
+
85 85
     def get_cookie_basket(self, cookie_key, request, manager):
86 86
         """
87 87
         Looks for a basket which is referenced by a cookie.
88
-        
88
+
89 89
         If a cookie key is found with no matching basket, then we add
90 90
         it to the list to be deleted.
91 91
         """
@@ -103,11 +103,11 @@ class BasketMiddleware(object):
103 103
                     self.cookies_to_delete.append(cookie_key)
104 104
             else:
105 105
                 self.cookies_to_delete.append(cookie_key)
106
-        return basket    
107
-    
106
+        return basket
107
+
108 108
     def apply_offers_to_basket(self, request, basket):
109 109
         if not basket.is_empty:
110 110
             Applicator().apply(request, basket)
111
-    
111
+
112 112
     def get_basket_hash(self, basket_id):
113 113
         return str(zlib.crc32(str(basket_id)+settings.SECRET_KEY))

+ 3
- 4
oscar/apps/basket/views.py View File

@@ -45,15 +45,15 @@ class BasketView(ModelFormSetView):
45 45
 
46 46
     def get_upsell_messages(self, basket):
47 47
         offers = Applicator().get_offers(self.request, basket)
48
-        messages = []
48
+        msgs = []
49 49
         for offer in offers:
50 50
             if offer.is_condition_partially_satisfied(basket):
51 51
                 data = {
52 52
                     'message': offer.get_upsell_message(basket),
53 53
                     'offer': offer
54 54
                 }
55
-                messages.append(data)
56
-        return messages
55
+                msgs.append(data)
56
+        return msgs
57 57
 
58 58
     def get_context_data(self, **kwargs):
59 59
         context = super(BasketView, self).get_context_data(**kwargs)
@@ -192,7 +192,6 @@ class VoucherAddView(FormView):
192 192
                              voucher=voucher)
193 193
 
194 194
         # Recalculate discounts to see if the voucher gives any
195
-        discounts_before = self.request.basket.get_discounts()
196 195
         self.request.basket.remove_discounts()
197 196
         Applicator().apply(self.request, self.request.basket)
198 197
         discounts_after = self.request.basket.get_discounts()

+ 91
- 91
oscar/apps/catalogue/abstract_models.py View File

@@ -162,7 +162,7 @@ class AbstractProductCategory(models.Model):
162 162
     product = models.ForeignKey('catalogue.Product')
163 163
     category = models.ForeignKey('catalogue.Category')
164 164
     is_canonical = models.BooleanField(_('is cannonical'), default=False, db_index=True)
165
-    
165
+
166 166
     class Meta:
167 167
         abstract = True
168 168
         ordering = ['-is_canonical']
@@ -171,7 +171,7 @@ class AbstractProductCategory(models.Model):
171 171
 
172 172
     def __unicode__(self):
173 173
         return u"<productcategory for product '%s'>" % self.product
174
-        
174
+
175 175
 
176 176
 class AbstractContributorRole(models.Model):
177 177
     """
@@ -180,10 +180,10 @@ class AbstractContributorRole(models.Model):
180 180
     name = models.CharField(_('name'), max_length=50)
181 181
     name_plural = models.CharField(_('name plural'), max_length=50)
182 182
     slug = models.SlugField()
183
-    
183
+
184 184
     def __unicode__(self):
185 185
         return self.name
186
-    
186
+
187 187
     class Meta:
188 188
         abstract = True
189 189
         verbose_name = _('Contributor Role')
@@ -192,7 +192,7 @@ class AbstractContributorRole(models.Model):
192 192
     def save(self, *args, **kwargs):
193 193
         if not self.slug:
194 194
             self.slug = slugify(self.name)
195
-        super(AbstractContributorRole, self).save(*args, **kwargs) 
195
+        super(AbstractContributorRole, self).save(*args, **kwargs)
196 196
 
197 197
 
198 198
 class AbstractContributor(models.Model):
@@ -204,7 +204,7 @@ class AbstractContributor(models.Model):
204 204
 
205 205
     def __unicode__(self):
206 206
         return self.name
207
-    
207
+
208 208
     class Meta:
209 209
         abstract = True
210 210
         verbose_name = _('Contributor')
@@ -221,14 +221,14 @@ class AbstractProductContributor(models.Model):
221 221
     product = models.ForeignKey('catalogue.Product')
222 222
     contributor = models.ForeignKey('catalogue.Contributor')
223 223
     role = models.ForeignKey('catalogue.ContributorRole', blank=True, null=True)
224
-    
224
+
225 225
     def __unicode__(self):
226 226
         return '%s <- %s - %s' % (self.product, self.role, self.contributor)
227
-    
227
+
228 228
     class Meta:
229 229
         abstract = True
230
-        verbose_name = _('Product Contributor')
231
-        verbose_name_plural = _('Product COntributors')
230
+        verbose_name = _('Product contributor')
231
+        verbose_name_plural = _('Product contributors')
232 232
 
233 233
 
234 234
 class AbstractProduct(models.Model):
@@ -238,21 +238,21 @@ class AbstractProduct(models.Model):
238 238
     # If an item has no parent, then it is the "canonical" or abstract version of a product
239 239
     # which essentially represents a set of products.  If a product has a parent
240 240
     # then it is a specific version of a catalogue.
241
-    # 
242
-    # For example, a canonical product would have a title like "Green fleece" while its 
241
+    #
242
+    # For example, a canonical product would have a title like "Green fleece" while its
243 243
     # children would be "Green fleece - size L".
244
-    
244
+
245 245
     # Universal product code
246 246
     upc = models.CharField(_("UPC"), max_length=64, blank=True, null=True, unique=True,
247 247
         help_text=_("""Universal Product Code (UPC) is an identifier for a product which is
248 248
                      not specific to a particular supplier.  Eg an ISBN for a book."""))
249
-    
249
+
250 250
     # No canonical product should have a stock record as they cannot be bought.
251 251
     parent = models.ForeignKey('self', null=True, blank=True, related_name='variants',
252 252
         help_text=_("""Only choose a parent product if this is a 'variant' of a canonical catalogue.  For example
253
-                     if this is a size 4 of a particular t-shirt.  Leave blank if this is a CANONICAL PRODUCT (ie 
253
+                     if this is a size 4 of a particular t-shirt.  Leave blank if this is a CANONICAL PRODUCT (ie
254 254
                      there is only one version of this product)."""))
255
-    
255
+
256 256
     # Title is mandatory for canonical products but optional for child products
257 257
     title = models.CharField(_('Title'), max_length=255, blank=True, null=True)
258 258
     slug = models.SlugField(_('Slug'), max_length=255, unique=False)
@@ -267,23 +267,23 @@ class AbstractProduct(models.Model):
267 267
     product_options = models.ManyToManyField('catalogue.Option', blank=True,
268 268
         help_text=_("""Options are values that can be associated with a item when it is added to
269 269
                      a customer's basket.  This could be something like a personalised message to be
270
-                     printed on a T-shirt.<br/>"""))
271
-    
270
+                     printed on a T-shirt."""))
271
+
272 272
     related_products = models.ManyToManyField('catalogue.Product', related_name='relations', blank=True,
273 273
         help_text=_("""Related items are things like different formats of the same book.  Grouping them together allows
274
-                     better linking betwen products on the site.<br/>"""))
275
-    
274
+                     better linking betwen products on the site."""))
275
+
276 276
     # Recommended products
277 277
     recommended_products = models.ManyToManyField('catalogue.Product', through='ProductRecommendation', blank=True)
278
-    
278
+
279 279
     # Product score
280 280
     score = models.FloatField(_('Score'), default=0.00, db_index=True)
281
-    
281
+
282 282
     date_created = models.DateTimeField(auto_now_add=True)
283 283
 
284 284
     # This field is used by Haystack to reindex search
285 285
     date_updated = models.DateTimeField(auto_now=True, db_index=True)
286
-    
286
+
287 287
     categories = models.ManyToManyField('catalogue.Category', through='ProductCategory')
288 288
 
289 289
     is_discountable = models.BooleanField(default=True)
@@ -304,15 +304,15 @@ class AbstractProduct(models.Model):
304 304
     def is_top_level(self):
305 305
         u"""Return True if this is a parent product"""
306 306
         return self.parent_id == None
307
-    
307
+
308 308
     @property
309 309
     def is_group(self):
310 310
         u"""Return True if this is a top level product and has more than 0 variants"""
311 311
         # use len() instead of count() in this specific instance
312
-        # as variants are highly likely to be used after this 
312
+        # as variants are highly likely to be used after this
313 313
         # which reduces the amount of SQL queries required
314 314
         return self.is_top_level and len(self.variants.all()) > 0
315
-    
315
+
316 316
     @property
317 317
     def is_variant(self):
318 318
         u"""Return True if a product is not a top level product"""
@@ -326,7 +326,7 @@ class AbstractProduct(models.Model):
326 326
     def min_variant_price_incl_tax(self):
327 327
         u"""Return minimum variant price including tax"""
328 328
         return self._min_variant_price('price_incl_tax')
329
-    
329
+
330 330
     @property
331 331
     def min_variant_price_excl_tax(self):
332 332
         u"""Return minimum variant price excluding tax"""
@@ -352,7 +352,7 @@ class AbstractProduct(models.Model):
352 352
     def add_category_from_breadcrumbs(self, breadcrumb):
353 353
         from oscar.apps.catalogue.utils import breadcrumbs_to_category
354 354
         category = breadcrumbs_to_category(breadcrumb)
355
-        
355
+
356 356
         temp = models.get_model('product', 'productcategory')(category=category, product=self)
357 357
         temp.save()
358 358
 
@@ -366,7 +366,7 @@ class AbstractProduct(models.Model):
366 366
         if not title and self.parent_id:
367 367
             title = self.parent.title
368 368
         return title
369
-    
369
+
370 370
     def get_product_class(self):
371 371
         """
372 372
         Return a product's item class
@@ -388,7 +388,7 @@ class AbstractProduct(models.Model):
388 388
         }
389 389
 
390 390
     # Helpers
391
-    
391
+
392 392
     def _min_variant_price(self, property):
393 393
         u"""Return minimum variant price"""
394 394
         prices = []
@@ -410,30 +410,30 @@ class AbstractProduct(models.Model):
410 410
         if self.is_variant:
411 411
             return u"%s (%s)" % (self.get_title(), self.attribute_summary())
412 412
         return self.get_title()
413
-    
413
+
414 414
     @models.permalink
415 415
     def get_absolute_url(self):
416 416
         u"""Return a product's absolute url"""
417 417
         return ('catalogue:detail', (), {
418 418
             'product_slug': self.slug,
419 419
             'pk': self.id})
420
-        
420
+
421 421
     def __init__(self, *args, **kwargs):
422 422
         super(AbstractProduct, self).__init__(*args, **kwargs)
423 423
         self.attr = ProductAttributesContainer(product=self)
424
-    
424
+
425 425
     def save(self, *args, **kwargs):
426 426
         if self.is_top_level and not self.title:
427 427
             raise ValidationError(_("Canonical products must have a title"))
428 428
         if not self.slug:
429 429
             self.slug = slugify(self.get_title())
430
-        
430
+
431 431
         # Validate attributes if necessary
432 432
         self.attr.validate_attributes()
433
-            
433
+
434 434
         # Save product
435 435
         super(AbstractProduct, self).save(*args, **kwargs)
436
-        
436
+
437 437
         # Finally, save attributes
438 438
         self.attr.save()
439 439
 
@@ -447,15 +447,15 @@ class ProductRecommendation(models.Model):
447 447
     ranking = models.PositiveSmallIntegerField(_('Ranking'), default=0)
448 448
 
449 449
     class Meta:
450
-        verbose_name = _('Product Recommendation')
451
-        verbose_name_plural = _('Product Recomendations')
450
+        verbose_name = _('Product recommendation')
451
+        verbose_name_plural = _('Product recomendations')
452 452
 
453 453
 
454 454
 class ProductAttributesContainer(object):
455 455
     """
456 456
     Stolen liberally from django-eav, but simplified to be product-specific
457 457
     """
458
-    
458
+
459 459
     def __init__(self, product):
460 460
         self.product = product
461 461
         self.initialised = False
@@ -472,9 +472,9 @@ class ProductAttributesContainer(object):
472 472
             if result:
473 473
                 return result
474 474
         raise AttributeError((_(u"%(obj)s has no attribute named " \
475
-                                       u"'%(attr)s'") % \
476
-                                     {'obj': self.product.product_class, 'attr': name}))
477
-        
475
+                                u"'%(attr)s'") % \
476
+                              {'obj': self.product.product_class, 'attr': name}))
477
+
478 478
     def validate_attributes(self):
479 479
         for attribute in self.get_all_attributes():
480 480
             value = getattr(self, attribute.code, None)
@@ -490,22 +490,22 @@ class ProductAttributesContainer(object):
490 490
                     raise ValidationError(_(u"%(attr)s attribute %(err)s") % \
491 491
                                             {'attr': attribute.code,
492 492
                                              'err': e})
493
-        
493
+
494 494
     def get_values(self):
495 495
         return self.product.attribute_values.all()
496
-    
496
+
497 497
     def get_value_by_attribute(self, attribute):
498
-        return self.get_values().get(attribute=attribute)    
499
-    
498
+        return self.get_values().get(attribute=attribute)
499
+
500 500
     def get_all_attributes(self):
501 501
         return self.product.get_product_class().attributes.all()
502
-    
502
+
503 503
     def get_attribute_by_code(self, code):
504 504
         return self.get_all_attributes().get(code=code)
505
-    
505
+
506 506
     def __iter__(self):
507 507
         return iter(self.get_values())
508
-    
508
+
509 509
     def save(self):
510 510
         for attribute in self.get_all_attributes():
511 511
             if hasattr(self, attribute.code):
@@ -514,7 +514,7 @@ class ProductAttributesContainer(object):
514 514
 
515 515
 
516 516
 class AbstractProductAttribute(models.Model):
517
-    
517
+
518 518
     TYPE_CHOICES = (
519 519
         ("text", _("Text")),
520 520
         ("integer", _("Integer")),
@@ -525,7 +525,7 @@ class AbstractProductAttribute(models.Model):
525 525
         ("option", _("Option")),
526 526
         ("entity", _("Entity"))
527 527
     )
528
-    
528
+
529 529
     """
530 530
     Defines an attribute for a product class. (For example, number_of_pages for a 'book' class)
531 531
     """
@@ -541,10 +541,10 @@ class AbstractProductAttribute(models.Model):
541 541
     required = models.BooleanField(_('required'), default=False)
542 542
 
543 543
     class Meta:
544
-        abstract = True 
544
+        abstract = True
545 545
         ordering = ['code']
546
-        verbose_name = _('Product Attribute')
547
-        verbose_name_plural = _('Product Attributes')
546
+        verbose_name = _('Product attribute')
547
+        verbose_name_plural = _('Product attributes')
548 548
 
549 549
     def _validate_text(self, value):
550 550
         if not (type(value) == unicode or type(value) == str):
@@ -587,7 +587,7 @@ class AbstractProductAttribute(models.Model):
587 587
         if value not in valid_values:
588 588
             raise ValidationError(_(u"%(enum)s is not a valid choice "
589 589
                                         u"for %(attr)s") % \
590
-                                       {'enum': value, 'attr': self})        
590
+                                       {'enum': value, 'attr': self})
591 591
 
592 592
     def get_validator(self):
593 593
         DATATYPE_VALIDATORS = {
@@ -601,14 +601,14 @@ class AbstractProductAttribute(models.Model):
601 601
             'option': self._validate_option,
602 602
         }
603 603
 
604
-        return DATATYPE_VALIDATORS[self.type]     
604
+        return DATATYPE_VALIDATORS[self.type]
605 605
 
606 606
     def __unicode__(self):
607 607
         return self.name
608 608
 
609 609
     def save(self, *args, **kwargs):
610 610
         super(AbstractProductAttribute, self).save(*args, **kwargs)
611
-        
611
+
612 612
     def save_value(self, product, value):
613 613
         try:
614 614
             value_obj = product.attribute_values.get(attribute=self)
@@ -622,10 +622,10 @@ class AbstractProductAttribute(models.Model):
622 622
         if value != value_obj.value:
623 623
             value_obj.value = value
624 624
             value_obj.save()
625
-    
625
+
626 626
     def validate_value(self, value):
627 627
         self.get_validator()(value)
628
-        
628
+
629 629
     def is_value_valid(self, value):
630 630
         """
631 631
         Check whether the passed value is valid for this attribute
@@ -639,9 +639,9 @@ class AbstractProductAttribute(models.Model):
639 639
 class AbstractProductAttributeValue(models.Model):
640 640
     """
641 641
     The "through" model for the m2m relationship between catalogue.Product
642
-    and catalogue.ProductAttribute.  
642
+    and catalogue.ProductAttribute.
643 643
     This specifies the value of the attribute for a particular product
644
-    
644
+
645 645
     For example: number_of_pages = 295
646 646
     """
647 647
     attribute = models.ForeignKey('catalogue.ProductAttribute')
@@ -654,18 +654,18 @@ class AbstractProductAttributeValue(models.Model):
654 654
     value_date = models.DateField(_('date'), blank=True, null=True)
655 655
     value_option = models.ForeignKey('catalogue.AttributeOption', blank=True, null=True)
656 656
     value_entity = models.ForeignKey('catalogue.AttributeEntity', blank=True, null=True)
657
-    
657
+
658 658
     def _get_value(self):
659 659
         return getattr(self, 'value_%s' % self.attribute.type)
660
-    
660
+
661 661
     def _set_value(self, new_value):
662 662
         if self.attribute.type == 'option' and isinstance(new_value, str):
663 663
             # Need to look up instance of AttributeOption
664 664
             new_value = self.attribute.option_group.options.get(option=new_value)
665 665
         setattr(self, 'value_%s' % self.attribute.type, new_value)
666
-    
666
+
667 667
     value = property(_get_value, _set_value)
668
-    
668
+
669 669
     class Meta:
670 670
         abstract = True
671 671
         verbose_name = _('Product Attribute Value')
@@ -673,19 +673,19 @@ class AbstractProductAttributeValue(models.Model):
673 673
 
674 674
     def __unicode__(self):
675 675
         return u"%s: %s" % (self.attribute.name, self.value)
676
-    
677
-    
676
+
677
+
678 678
 class AbstractAttributeOptionGroup(models.Model):
679 679
     """
680
-    Defines a group of options that collectively may be used as an 
680
+    Defines a group of options that collectively may be used as an
681 681
     attribute type
682 682
     For example, Language
683 683
     """
684 684
     name = models.CharField(_('name'), max_length=128)
685
-    
685
+
686 686
     def __unicode__(self):
687 687
         return self.name
688
-    
688
+
689 689
     class Meta:
690 690
         abstract = True
691 691
         verbose_name = _('Attribute Option Group')
@@ -699,14 +699,14 @@ class AbstractAttributeOption(models.Model):
699 699
     """
700 700
     group = models.ForeignKey('catalogue.AttributeOptionGroup', related_name='options')
701 701
     option = models.CharField(_('option'), max_length=255)
702
-    
702
+
703 703
     def __unicode__(self):
704 704
         return self.option
705
-    
705
+
706 706
     class Meta:
707 707
         abstract = True
708
-        verbose_name = _('Attribute Option')
709
-        verbose_name_plural = _('Attribute Options')
708
+        verbose_name = _('Attribute option')
709
+        verbose_name_plural = _('Attribute options')
710 710
 
711 711
 
712 712
 class AbstractAttributeEntity(models.Model):
@@ -719,7 +719,7 @@ class AbstractAttributeEntity(models.Model):
719 719
 
720 720
     def __unicode__(self):
721 721
         return self.name
722
-    
722
+
723 723
     class Meta:
724 724
         abstract = True
725 725
         verbose_name = _('Attribute entity')
@@ -737,10 +737,10 @@ class AbstractAttributeEntityType(models.Model):
737 737
     """
738 738
     name = models.CharField(_("Name"), max_length=255)
739 739
     slug = models.SlugField(_("Slug"), max_length=255, unique=False, blank=True)
740
-    
740
+
741 741
     def __unicode__(self):
742 742
         return self.name
743
-        
743
+
744 744
     class Meta:
745 745
         abstract = True
746 746
         verbose_name = _('Attribute Entity Type')
@@ -750,29 +750,29 @@ class AbstractAttributeEntityType(models.Model):
750 750
         if not self.slug:
751 751
             self.slug = slugify(self.name)
752 752
         super(AbstractAttributeEntityType, self).save(*args, **kwargs)
753
-    
754
-    
753
+
754
+
755 755
 class AbstractOption(models.Model):
756 756
     u"""
757 757
     An option that can be selected for a particular item when the product
758
-    is added to the basket.  
759
-    
760
-    Eg a list ID for an SMS message send, or a personalised message to 
761
-    print on a T-shirt.  
762
-    
763
-    This is not the same as an attribute as options do not have a fixed value for 
758
+    is added to the basket.
759
+
760
+    Eg a list ID for an SMS message send, or a personalised message to
761
+    print on a T-shirt.
762
+
763
+    This is not the same as an attribute as options do not have a fixed value for
764 764
     a particular item - options, they need to be specified by the customer.
765 765
     """
766 766
     name = models.CharField(_('name'), max_length=128)
767 767
     code = models.SlugField(_('code'), max_length=128)
768
-    
768
+
769 769
     REQUIRED, OPTIONAL = ('Required', 'Optional')
770 770
     TYPE_CHOICES = (
771 771
         (REQUIRED, _("Required - a value for this option must be specified")),
772 772
         (OPTIONAL, _("Optional - a value for this option can be omitted")),
773 773
     )
774 774
     type = models.CharField(_("Status"), max_length=128, default=REQUIRED, choices=TYPE_CHOICES)
775
-    
775
+
776 776
     class Meta:
777 777
         abstract = True
778 778
         verbose_name = _('Option')
@@ -780,7 +780,7 @@ class AbstractOption(models.Model):
780 780
 
781 781
     def __unicode__(self):
782 782
         return self.name
783
-    
783
+
784 784
     def save(self, *args, **kwargs):
785 785
         if not self.code:
786 786
             self.code = slugify(self.name)
@@ -800,13 +800,13 @@ class AbstractProductImage(models.Model):
800 800
     product = models.ForeignKey('catalogue.Product', related_name='images')
801 801
     original = models.ImageField(_("Original"), upload_to=settings.OSCAR_IMAGE_FOLDER)
802 802
     caption = models.CharField(_("Caption"), max_length=200, blank=True, null=True)
803
-    
803
+
804 804
     # Use display_order to determine which is the "primary" image
805 805
     display_order = models.PositiveIntegerField(_("Display Order"), default=0,
806 806
         help_text=_("""An image with a display order of
807 807
                        zero will be the primary image for a product"""))
808 808
     date_created = models.DateTimeField(auto_now_add=True)
809
-    
809
+
810 810
     class Meta:
811 811
         abstract = True
812 812
         unique_together = ("product", "display_order")
@@ -834,7 +834,7 @@ class AbstractProductImage(models.Model):
834 834
         images in a specific way.
835 835
         """
836 836
         return self.resized_image_url()
837
-    
837
+
838 838
     @property
839 839
     def thumbnail_url(self):
840 840
         return self.resized_image_url()

+ 4
- 0
oscar/apps/catalogue/categories.py View File

@@ -4,6 +4,9 @@ Category = get_model('catalogue', 'category')
4 4
 
5 5
 
6 6
 def create_from_sequence(bits):
7
+    """
8
+    Create categories from an iterable
9
+    """
7 10
     if len(bits) == 1:
8 11
         # Get or create root node
9 12
         try:
@@ -20,6 +23,7 @@ def create_from_sequence(bits):
20 23
         parents.append(child)
21 24
         return parents
22 25
 
26
+
23 27
 def create_from_breadcrumbs(breadcrumb_str, separator='>'):
24 28
     """
25 29
     Create categories from a breadcrumb string

+ 1
- 2
oscar/apps/catalogue/views.py View File

@@ -131,7 +131,6 @@ class ProductListView(ListView):
131 131
         if q:
132 132
             # Send signal to record the view of this product
133 133
             self.search_signal.send(sender=self, query=q, user=self.request.user)
134
-            base_queryset = get_product_base_queryset()
135 134
             return get_product_base_queryset().filter(title__icontains=q)
136 135
         else:
137 136
             return get_product_base_queryset()
@@ -142,6 +141,6 @@ class ProductListView(ListView):
142 141
         if not q:
143 142
             context['summary'] = _('All products')
144 143
         else:
145
-            context['summary'] = _("Products matching '%s'") % q
144
+            context['summary'] = _("Products matching '%(query)s'") % {'query': q}
146 145
             context['search_term'] = q
147 146
         return context

Loading…
Cancel
Save