Procházet zdrojové kódy

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

master
Viggo de Vries před 5 roky
rodič
revize
603944d1dd
Žádný účet není propojen s e-mailovou adresou tvůrce revize

+ 2
- 0
docs/source/releases/v3.0.rst Zobrazit soubor

77
 
77
 
78
 - Category slugs can now be edited via the dashboard.
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
 Dependency changes
82
 Dependency changes
81
 ~~~~~~~~~~~~~~~~~~
83
 ~~~~~~~~~~~~~~~~~~
82
 
84
 

+ 11
- 1
src/oscar/apps/catalogue/abstract_models.py Zobrazit soubor

599
         """
599
         """
600
         Return a string of all of a product's attributes
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
         pairs = [attribute.summary() for attribute in attributes]
603
         pairs = [attribute.summary() for attribute in attributes]
604
         return ", ".join(pairs)
604
         return ", ".join(pairs)
605
 
605
 
643
             return self.categories
643
             return self.categories
644
     get_categories.short_description = _("Categories")
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
     # Images
656
     # Images
647
 
657
 
648
     def get_missing_image(self):
658
     def get_missing_image(self):

+ 1
- 1
src/oscar/apps/catalogue/product_attributes.py Zobrazit soubor

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

+ 2
- 7
src/oscar/apps/shipping/scales.py Zobrazit soubor

14
     def weigh_product(self, product):
14
     def weigh_product(self, product):
15
         weight = None
15
         weight = None
16
         try:
16
         try:
17
-            weight = product.attribute_values.get(
17
+            weight = product.get_attribute_values().get(
18
                 attribute__code=self.attribute).value
18
                 attribute__code=self.attribute).value
19
         except ObjectDoesNotExist:
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
         if weight is None:
22
         if weight is None:
28
             if self.default_weight is None:
23
             if self.default_weight is None:

+ 1
- 1
src/oscar/templates/oscar/catalogue/detail.html Zobrazit soubor

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

+ 47
- 0
tests/integration/catalogue/test_product.py Zobrazit soubor

81
             product_class=self.product_class,
81
             product_class=self.product_class,
82
             structure=Product.PARENT,
82
             structure=Product.PARENT,
83
             is_discountable=False)
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
     def test_child_products_dont_need_titles(self):
95
     def test_child_products_dont_need_titles(self):
86
         Product.objects.create(
96
         Product.objects.create(
104
             structure=Product.CHILD)
114
             structure=Product.CHILD)
105
         self.assertEqual(set([self.parent]), set(Product.objects.browsable()))
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
 class TestAChildProduct(TestCase):
155
 class TestAChildProduct(TestCase):
109
 
156
 

Načítá se…
Zrušit
Uložit