Automapper 是一个对象-对象映射器,我们可以使用它来投影域模型以在 ASP.NET MVC 中查看模型。
http://automapper.codeplex.com/
Python 中是否有用于 Django(Template)/Pylons 的等效实现? 或者Python世界有必要这样做吗?
是的,有。
ObjectMapper 是一个用于自动对象映射的类。它可以帮助您以简单、透明的方式在项目层(数据层、服务层、视图)之间创建对象。
这在 Python 中通常是不必要的。 我们有一些非常复杂的域模型,我们能够在我们的视图中轻松使用它们,而不会注意到任何性能问题,并且我们每月提供数百万的页面视图。
还要记住,Django 中的“视图”== MVC 中的“控制器”,Django 中的“模板”就是 MVC 中的“视图”。 因此 MTV 而不是 MVC。 最初让我绊倒的事情:-)
如果您遇到一些具体问题,也可以将其作为问题发布......
这是一个很好的 Python 自动映射器,可以扩展到任何框架模型:
我最终推出了自己的基于 .net 版本的 Automapper 基本版本。
from typing import Protocol, TypeVar, Callable
from dataclasses import is_dataclass, fields
from dataclasses import MISSING
S = TypeVar("S")
T = TypeVar("T")
class IProfile(Protocol):
mappings: dict[tuple[type[S], type[T]], dict[str, Callable[[S], object]]]
def create_map(self,
source_type: type[S],
target_type: type[T],
**mappings: Callable[[S], object]) -> None:
...
class IMapper(Protocol):
def map(self, data: object, data_type: type[T]) -> T:
...
class Profile:
mappings: dict[tuple[type[S], type[T]], dict[str, Callable[[S], object]]]
def __init__(self) -> None:
self.mappings = {}
def create_map(self,
source_type: type[S],
target_type: type[T],
**mappings: Callable[[S], object]) -> None:
self.mappings[(source_type, target_type)] = dict(mappings)
class Mapper:
_mappings: dict[tuple[type[S], type[T]], dict[str, Callable[[S], object]]]
def __init__(self, profiles: list[IProfile]) -> None:
self._mappings = {}
for profile in profiles:
for key, value in profile.mappings.items():
self._mappings[key] = value
def map(self, data: object, data_type: type[T]) -> T:
if not is_dataclass(data_type):
raise TypeError("type must be a dataclass")
mapping_key = (type(data), data_type,)
data_fields = fields(data_type)
data_params = {}
mappings = self._mappings.get(mapping_key, {})
for field in data_fields:
field_name, field_type = field.name, field.type
field_value = getattr(data, field_name, None)
if is_dataclass(field_type):
field_value = self.map(field_value, field_type)
else:
if field_name in mappings:
field_value = mappings[field_name](field_value)
if not field_value and field.default is not MISSING:
field_value = field.default
data_params[field_name] = field_value
return data_type(**data_params)
我不会说它是完美的,但它足以满足我的要求。
https://gist.github.com/ahancock1/5e5e0c665c3e696f1e8085f7b38bd123
我能想到的在 python 中映射对象的最简单方法是让它们具有某种静态
adapt_...
方法。看起来是这样的:
class PostResponse:
id: int
title: str
text: str
created_at: str
@classmethod
def adapt_db(cls, db_post: Post) -> Self:
model = cls(**{
# basic mapping of identical fields
**db_post.__dict__,
# adjustments for concrete mismatches
'created_at': str(db_post.created_at)
})
return model
db_post = find_post_in_db()
post_response = PostResponse.adapt_db(db_post)