Skip to content

Commit

Permalink
Cleanup and warn of future deprecations
Browse files Browse the repository at this point in the history
  • Loading branch information
specialunderwear committed Oct 9, 2023
1 parent 730c343 commit 3263221
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 49 deletions.
13 changes: 10 additions & 3 deletions oscarapi/serializers/fields.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# pylint: disable=W0212, W0201, W0632
import logging
import operator
import warnings

from os.path import basename, join
from urllib.parse import urlsplit, parse_qs
Expand All @@ -15,6 +16,7 @@
from rest_framework.fields import get_attribute

from oscar.core.loading import get_model, get_class
from oscarapi.utils.deprecations import RemovedInOScarAPI4

from oscarapi import settings
from oscarapi.utils.attributes import AttributeFieldBase, attribute_details
Expand Down Expand Up @@ -103,6 +105,11 @@ class AttributeValueField(AttributeFieldBase, serializers.Field):
"""

def __init__(self, **kwargs):
warnings.warn(
"AttributeValueField is deprecated and will be removed in a future version of oscarapi",
RemovedInOScarAPI4,
stacklevel=2,
)
# this field always needs the full object
kwargs["source"] = "*"
super(AttributeValueField, self).__init__(**kwargs)
Expand All @@ -126,8 +133,8 @@ def get_data_attribute(self, data):
code=data["code"], product_class__products__id=data["parent"]
)

def convert_to_internal_value(self, attribute, code, value):
internal_value = super().convert_to_internal_value(attribute, code, value)
def to_attribute_type_value(self, attribute, code, value):
internal_value = super().to_attribute_type_value(attribute, code, value)
if attribute.type in [
attribute.IMAGE,
attribute.FILE,
Expand All @@ -147,7 +154,7 @@ def to_internal_value(self, data): # noqa

attribute = self.get_data_attribute(data)

internal_value = self.convert_to_internal_value(attribute, code, value)
internal_value = self.to_attribute_type_value(attribute, code, value)

# the rest of the attribute types don't need special processing
try:
Expand Down
92 changes: 47 additions & 45 deletions oscarapi/serializers/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,48 @@ class Meta:


class ProductAttributeValueListSerializer(UpdateListSerializer):
# pylint: disable=unused-argument
def shortcut_to_internal_value(self, data, productclass, attributes):
difficult_attributes = {
at.code: at
for at in productclass.attributes.filter(
type__in=[
ProductAttribute.OPTION,
ProductAttribute.MULTI_OPTION,
ProductAttribute.DATE,
ProductAttribute.DATETIME,
ProductAttribute.ENTITY,
]
)
}
cv = AttributeConverter(self.context)
internal_value = []
for item in data:
code, value = getitems(item, "code", "value")
if code is None: # delegate error state to child serializer
internal_value.append(self.child.to_internal_value(item))

if code in difficult_attributes:
attribute = difficult_attributes[code]
converted_value = cv.to_attribute_type_value(attribute, code, value)
internal_value.append(
{
"value": converted_value,
"attribute": attribute,
"product_class": productclass,
}
)
else:
internal_value.append(
{
"value": value,
"attribute": code,
"product_class": productclass,
}
)

return internal_value

def to_internal_value(self, data):
productclasses = set()
attributes = set()
Expand All @@ -207,52 +249,13 @@ def to_internal_value(self, data):
attributes.add(code)

# if all attributes belong to the same productclass, everything is just
# as expected and we can do an optimization by only resolving the productclass to the model instance and nothing else.
# as expected and we can take a shortcut by only resolving the
# productclass to the model instance and nothing else.
try:
if len(productclasses) == 1 and all(attributes):
(product_class,) = productclasses
pc = ProductClass.objects.get(slug=product_class)
difficult_attributes = {
at.code: at
for at in pc.attributes.filter(
type__in=[
ProductAttribute.OPTION,
ProductAttribute.MULTI_OPTION,
ProductAttribute.DATE,
ProductAttribute.DATETIME,
ProductAttribute.ENTITY,
]
)
}
cv = AttributeConverter(self.context)
internal_value = []
for item in data:
code, value = getitems(item, "code", "value")
if code is None:
internal_value.append(self.child.to_internal_value(item))

if code in difficult_attributes:
attribute = difficult_attributes[code]
converted_value = cv.convert_to_internal_value(
attribute, code, value
)
internal_value.append(
{
"value": converted_value,
"attribute": attribute,
"product_class": pc,
}
)
else:
internal_value.append(
{
"value": value,
"attribute": code,
"product_class": pc,
}
)
return internal_value

return self.shortcut_to_internal_value(data, pc, attributes)
except ProductClass.DoesNotExist:
pass

Expand Down Expand Up @@ -293,18 +296,17 @@ def update(self, instance, validated_data):
if hasattr(
attribute, "code"
): # if the attribute is a model instance use the code
product.attr.set(attribute.code, value)
product.attr.set(attribute.code, value, validate_identifier=False)
attr_codes.append(attribute.code)
else:
product.attr.set(attribute, value)
product.attr.set(attribute, value, validate_identifier=False)
attr_codes.append(attribute)

# if we don't clear the dirty attributes all parent attributes
# are marked as explicitly set, so they will be copied to the
# child product.
product.attr._dirty.clear() # pylint: disable=protected-access
product.attr.save()

return list(product.attr.get_values().filter(attribute__code__in=attr_codes))


Expand Down
2 changes: 1 addition & 1 deletion oscarapi/utils/attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class AttributeFieldBase:
),
}

def convert_to_internal_value(self, attribute, code, value):
def to_attribute_type_value(self, attribute, code, value):
internal_value = value
# pylint: disable=no-member
if attribute.required and value is None:
Expand Down
2 changes: 2 additions & 0 deletions oscarapi/utils/deprecations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class RemovedInOScarAPI4(PendingDeprecationWarning):
pass

0 comments on commit 3263221

Please sign in to comment.