Skip to content

Commit

Permalink
feat: fields.MethodField
Browse files Browse the repository at this point in the history
  • Loading branch information
vinyguedess committed Nov 5, 2021
1 parent c4f735e commit 8ff010c
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 1 deletion.
4 changes: 4 additions & 0 deletions alcherializer/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,7 @@ def check_if_length_is_under_limit(
return False, f"Limit of characters is {self.field.type.length}"

return True, None


class MethodField(BaseField):
pass
16 changes: 16 additions & 0 deletions alcherializer/serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,19 @@ def _get_fields(self) -> Dict[str, Any]:
"validator": self._get_field_validator(key, value),
}

for field in required_fields:
if field in columns:
continue

if not hasattr(self, field):
continue

columns[field] = {
"type": getattr(self, field),
"required": False,
"validator": self._get_field_validator(field, field),
}

return columns

def _get_field_validator(self, key: str, field):
Expand All @@ -107,6 +120,9 @@ def _get_field_validator(self, key: str, field):
return fields.BaseField(key, field)

def _get_instance_field_value(self, instance, field: str) -> Any:
if isinstance(self.fields[field].get("type"), fields.MethodField):
return getattr(self, f"get_{field}", lambda o: None)(instance)

value = getattr(instance, field)
if isinstance(value.__class__, DeclarativeMeta):
serializer = self.fields[field]["validator"]
Expand Down
31 changes: 30 additions & 1 deletion tests/unit/serializer/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship

from alcherializer import Serializer
from alcherializer import (
Serializer,
fields,
)


def test_data_single_instance() -> None:
Expand Down Expand Up @@ -171,3 +174,29 @@ class Meta:
{"id": 1, "hello": "world"},
],
}


def test_data_get_method_fields() -> None:
class MyModel(declarative_base()):
id = sqlalchemy.Column(
sqlalchemy.Integer, primary_key=True, nullable=False
)
first_name = sqlalchemy.Column(sqlalchemy.String)
last_name = sqlalchemy.Column(sqlalchemy.String)

__tablename__ = "my_model"

class MyModelSerializer(Serializer):
full_name = fields.MethodField()

def get_full_name(self, obj: MyModel):
return f"{obj.first_name} {obj.last_name}"

class Meta:
model = MyModel
fields = ["id", "full_name"]

model = MyModel(id=1, first_name="hello", last_name="world")

serializer = MyModelSerializer(model)
assert serializer.data == {"id": 1, "full_name": "hello world"}

0 comments on commit 8ff010c

Please sign in to comment.