Skip to content

Commit

Permalink
Fix some errors
Browse files Browse the repository at this point in the history
  • Loading branch information
viggo-devries committed Nov 23, 2023
1 parent 3f9f974 commit 00fdcd5
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 57 deletions.
49 changes: 28 additions & 21 deletions oscar_odin/mappings/_model_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
from typing import Sequence, cast

from django.db.models.fields.related import ForeignKey, ManyToManyField
from django.db.models.fields.reverse_related import (
OneToOneRel,
ManyToOneRel,
ManyToManyRel,
)
from django.db.models.options import Options

from odin.mapping import MappingBase, MappingMeta
Expand All @@ -20,7 +25,6 @@ def __new__(cls, name, bases, attrs):
meta = cast(Options, getmeta(mapping_type.to_obj))

# Extract out foreign field types.
mapping_type.one_to_many_fields = one_to_many_fields = []
mapping_type.many_to_one_fields = many_to_one_fields = []
mapping_type.many_to_many_fields = many_to_many_fields = []
mapping_type.foreign_key_fields = [
Expand All @@ -30,11 +34,11 @@ def __new__(cls, name, bases, attrs):
# Break out related objects by their type
for relation in meta.related_objects:
if relation.many_to_many:
many_to_many_fields.append(relation.field)
many_to_many_fields.append(relation)
elif relation.many_to_one:
many_to_one_fields.append(relation.field)
many_to_one_fields.append(relation)
elif relation.one_to_many:
one_to_many_fields.append(relation.field)
many_to_one_fields.append(relation)

return mapping_type

Expand All @@ -46,35 +50,38 @@ class ModelMapping(MappingBase, metaclass=ModelMappingMeta):
mappings = []

# Specific fields
one_to_many_fields: Sequence[ManyToManyField] = []
many_to_one_fields: Sequence[ManyToManyField] = []
many_to_many_fields: Sequence[ManyToManyField] = []
many_to_one_fields: Sequence[ManyToOneRel] = []
many_to_many_fields: Sequence[ManyToManyRel] = []
foreign_key_fields: Sequence[ForeignKey] = []

def create_object(self, **field_values):
"""Create a new product model."""
many_to_one_items = [
(relation, field_values.pop(relation.related_name))
for relation in self.many_to_one_fields
if relation.related_name in field_values
]
many_to_many_items = [
(relation, field_values.pop(relation.related_name))
for relation in self.many_to_many_fields
if relation.related_name in field_values
]
foreign_key_items = [
(field, field_values.pop(field.name))
for field in self.foreign_key_fields
if field.name in field_values
]

parent = super().create_object(**field_values)

self.context["one_to_many_items"] = [
(parent, field, field_values.pop(field.name))
for field in self.one_to_many_fields
if field.name in field_values
]
self.context["many_to_one_items"] = [
(parent, field, field_values.pop(field.name))
for field in self.many_to_one_fields
if field.name in field_values
(parent, *item) for item in many_to_one_items
]
self.context["many_to_many_items"] = [
(parent, field, field_values.pop(field.name))
for field in self.many_to_many_fields
if field.name in field_values
(parent, *item) for item in many_to_many_items
]
self.context["foreign_key_items"] = [
(parent, field, field_values.pop(field.name))
for field in self.foreign_key_fields
if field.name in field_values
(parent, *item) for item in foreign_key_items
]

return parent
47 changes: 15 additions & 32 deletions oscar_odin/mappings/catalogue.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from datetime import datetime

from .. import resources
from ..utils import RelatedModels
from ..resources.catalogue import Structure
from ._common import map_queryset
from ._model_mapper import ModelMapping
Expand Down Expand Up @@ -57,7 +58,10 @@ class ProductImageToModel(odin.Mapping):
def original(self, value: str) -> str:
"""Convert value into a pure URL."""
# TODO convert into a form that can be accepted by a model
return value
if value:
return value

return "lege-image"

@odin.map_field
def date_created(self, value: datetime) -> datetime:
Expand Down Expand Up @@ -232,15 +236,10 @@ def children(self, values) -> List[ProductModel]:
"""Map related image."""
return []

@odin.map_field(from_field="product_class", to_field="product_class_id")
def product_class_id(self, value) -> ProductClassModel:
@odin.map_field
def product_class(self, value) -> ProductClassModel:
return ProductClassToModel.apply(value)

# @odin.assign_field
# def categories(self) -> List[CategoryModel]:
# """Map related categories."""
# return list(CategoryToModel.apply(self.source.categories, context=self.context))


def product_to_resource_with_strategy(
product: Union[ProductModel, Iterable[ProductModel]],
Expand Down Expand Up @@ -321,25 +320,6 @@ def product_queryset_to_resources(
)


ForeignRelationResult = Tuple[Model, ManyToManyField, Any]


class RelatedModels(NamedTuple):
@classmethod
def from_context(cls, context: dict):
return cls(
context["one_to_many_items"],
context["many_to_one_items"],
context["many_to_many_items"],
context["foreign_key_items"],
)

one_to_many_items: ForeignRelationResult
many_to_one_items: ForeignRelationResult
many_to_many_items: ForeignRelationResult
foreign_key_items: Tuple[Model, ForeignKey, Any]


def product_to_model(
product: resources.catalogue.Product,
) -> Tuple[ProductModel, RelatedModels]:
Expand All @@ -363,14 +343,17 @@ def product_to_db(

with transaction.atomic():
for parent, field, fk_instance in related_models.foreign_key_items:
fk_instance.full_clean()
fk_instance.save()
setattr(obj, fk_name, fk_instance.pk)
setattr(obj, field.name, fk_instance)

fk_instance.full_clean()
obj.save()

for mtm_name, mtm_attname, instances in context.get("many_to_many_items", []):
for mtm_instance in instances:
setattr(mtm_instance, mtm_attname, obj.pk)
mtm_instance.save()
for parent, relation, instances in related_models.related_items:
for instance in instances:
setattr(instance, relation.field.name, obj)
instance.full_clean()
instance.save()

return obj
11 changes: 7 additions & 4 deletions tests/reverse/test_catalogue.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def test_create_simple_product(self):
prd = product_to_db(product_resource)

prd = Product.objects.get(upc="1234323")

self.assertEquals(prd.title, "asdf1")

def test_create_product_with_related_fields(self):
Expand All @@ -42,13 +42,16 @@ def test_create_product_with_related_fields(self):
product_class=ProductClassResource(
name="Klaas", slug="klaas", requires_shipping=True, track_stock=True
),
images=[ImageResource(caption="gekke caption", display_order=0), ImageResource(caption="gekke caption 2", display_order=1)],
images=[
ImageResource(caption="gekke caption", display_order=0),
ImageResource(caption="gekke caption 2", display_order=1),
],
)

prd = product_to_db(product_resource)

prd = Product.objects.get(upc="1234323-2")

self.assertEquals(prd.title, "asdf2")

self.assertEquals(prd.images.count(), 2)

0 comments on commit 00fdcd5

Please sign in to comment.