Quellcode durchsuchen

Add method get_attribute_values to Product model which also fetches parent product attributes (#3514)

master
Viggo de Vries vor 5 Jahren
Ursprung
Commit
603944d1dd
Es ist kein Account mit der E-Mail-Adresse des Committers verbunden

+ 2
- 0
docs/source/releases/v3.0.rst Datei anzeigen

@@ -77,6 +77,8 @@ Minor changes
77 77
 
78 78
 - Category slugs can now be edited via the dashboard.
79 79
 
80
+- A new method get_attribute_values() was added to the Product model which returns a merged set of attribute values for child and parent products.
81
+
80 82
 Dependency changes
81 83
 ~~~~~~~~~~~~~~~~~~
82 84
 

+ 11
- 1
src/oscar/apps/catalogue/abstract_models.py Datei anzeigen

@@ -599,7 +599,7 @@ class AbstractProduct(models.Model):
599 599
         """
600 600
         Return a string of all of a product's attributes
601 601
         """
602
-        attributes = self.attribute_values.all()
602
+        attributes = self.get_attribute_values()
603 603
         pairs = [attribute.summary() for attribute in attributes]
604 604
         return ", ".join(pairs)
605 605
 
@@ -643,6 +643,16 @@ class AbstractProduct(models.Model):
643 643
             return self.categories
644 644
     get_categories.short_description = _("Categories")
645 645
 
646
+    def get_attribute_values(self):
647
+        attribute_values = self.attribute_values.all()
648
+        if self.is_child:
649
+            parent_attribute_values = self.parent.attribute_values.exclude(
650
+                attribute__code__in=attribute_values.values("attribute__code")
651
+            )
652
+            return attribute_values | parent_attribute_values
653
+
654
+        return attribute_values
655
+
646 656
     # Images
647 657
 
648 658
     def get_missing_image(self):

+ 1
- 1
src/oscar/apps/catalogue/product_attributes.py Datei anzeigen

@@ -41,7 +41,7 @@ class ProductAttributesContainer:
41 41
                         {'attr': attribute.code, 'err': e})
42 42
 
43 43
     def get_values(self):
44
-        return self.product.attribute_values.all()
44
+        return self.product.get_attribute_values()
45 45
 
46 46
     def get_value_by_attribute(self, attribute):
47 47
         return self.get_values().get(attribute=attribute)

+ 2
- 7
src/oscar/apps/shipping/scales.py Datei anzeigen

@@ -14,15 +14,10 @@ class Scale(object):
14 14
     def weigh_product(self, product):
15 15
         weight = None
16 16
         try:
17
-            weight = product.attribute_values.get(
17
+            weight = product.get_attribute_values().get(
18 18
                 attribute__code=self.attribute).value
19 19
         except ObjectDoesNotExist:
20
-            if product.parent:
21
-                try:
22
-                    weight = product.parent.attribute_values.get(
23
-                        attribute__code=self.attribute).value
24
-                except ObjectDoesNotExist:
25
-                    pass
20
+            pass
26 21
 
27 22
         if weight is None:
28 23
             if self.default_weight is None:

+ 1
- 1
src/oscar/templates/oscar/catalogue/detail.html Datei anzeigen

@@ -138,7 +138,7 @@
138 138
                 <td>{{ session.availability.message }}</td>
139 139
             </tr>
140 140
         {% endif %}
141
-        {% for av in product.attribute_values.all %}
141
+        {% for av in product.get_attribute_values %}
142 142
             <tr>
143 143
                 <th>{{ av.attribute.name }}</th>
144 144
                 <td>{{ av.value_as_html }}</td>

+ 47
- 0
tests/integration/catalogue/test_product.py Datei anzeigen

@@ -81,6 +81,16 @@ class ChildProductTests(ProductTests):
81 81
             product_class=self.product_class,
82 82
             structure=Product.PARENT,
83 83
             is_discountable=False)
84
+        ProductAttribute.objects.create(
85
+            product_class=self.product_class,
86
+            name='The first attribute',
87
+            code='first_attribute',
88
+            type='text')
89
+        ProductAttribute.objects.create(
90
+            product_class=self.product_class,
91
+            name='The second attribute',
92
+            code='second_attribute',
93
+            type='text')
84 94
 
85 95
     def test_child_products_dont_need_titles(self):
86 96
         Product.objects.create(
@@ -104,6 +114,43 @@ class ChildProductTests(ProductTests):
104 114
             structure=Product.CHILD)
105 115
         self.assertEqual(set([self.parent]), set(Product.objects.browsable()))
106 116
 
117
+    def test_child_products_attribute_values(self):
118
+        product = Product.objects.create(
119
+            product_class=self.product_class, parent=self.parent,
120
+            structure=Product.CHILD)
121
+
122
+        self.parent.attr.first_attribute = "klats"
123
+        product.attr.second_attribute = "henk"
124
+        self.parent.save()
125
+        product.save()
126
+
127
+        product = Product.objects.get(pk=product.pk)
128
+        parent = Product.objects.get(pk=self.parent.pk)
129
+
130
+        self.assertEqual(parent.get_attribute_values().count(), 1)
131
+        self.assertEqual(product.get_attribute_values().count(), 2)
132
+        self.assertTrue(hasattr(parent.attr, "first_attribute"))
133
+        self.assertFalse(hasattr(parent.attr, "second_attribute"))
134
+        self.assertTrue(hasattr(product.attr, "first_attribute"))
135
+        self.assertTrue(hasattr(product.attr, "second_attribute"))
136
+
137
+    def test_child_products_attribute_values_no_parent_values(self):
138
+        product = Product.objects.create(
139
+            product_class=self.product_class, parent=self.parent,
140
+            structure=Product.CHILD)
141
+
142
+        product.attr.second_attribute = "henk"
143
+        product.save()
144
+
145
+        product = Product.objects.get(pk=product.pk)
146
+
147
+        self.assertEqual(self.parent.get_attribute_values().count(), 0)
148
+        self.assertEqual(product.get_attribute_values().count(), 1)
149
+        self.assertFalse(hasattr(self.parent.attr, "first_attribute"))
150
+        self.assertFalse(hasattr(self.parent.attr, "second_attribute"))
151
+        self.assertFalse(hasattr(product.attr, "first_attribute"))
152
+        self.assertTrue(hasattr(product.attr, "second_attribute"))
153
+
107 154
 
108 155
 class TestAChildProduct(TestCase):
109 156
 

Laden…
Abbrechen
Speichern