Skip to content

ManyToMany class

edgy.ManyToManyField

Bases: ForeignKeyFieldFactory

methods_overwritable_by_factory class-attribute instance-attribute

methods_overwritable_by_factory = frozenset(default_methods_overwritable_by_factory)

field_bases class-attribute instance-attribute

field_bases = (BaseManyToManyForeignKeyField)

build_field classmethod

build_field(**kwargs)
PARAMETER DESCRIPTION
**kwargs

TYPE: Any DEFAULT: {}

Source code in edgy/core/db/fields/factories.py
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
@classmethod
def build_field(cls, **kwargs: Any) -> BaseFieldType:
    column_type = cls.get_column_type(**kwargs)
    pydantic_type = cls.get_pydantic_type(**kwargs)
    constraints = cls.get_constraints(**kwargs)

    new_field = cls._get_field_cls(cls)

    new_field_obj: BaseFieldType = new_field(  # type: ignore
        field_type=pydantic_type,
        annotation=pydantic_type,
        column_type=column_type,
        constraints=constraints,
        factory=cls,
        **kwargs,
    )
    cls.overwrite_methods(new_field_obj)
    return new_field_obj

overwrite_methods classmethod

overwrite_methods(field_obj)

Called in metaclasses

PARAMETER DESCRIPTION
field_obj

TYPE: BaseFieldType

Source code in edgy/core/db/fields/factories.py
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
@classmethod
def overwrite_methods(cls, field_obj: BaseFieldType) -> None:
    """Called in metaclasses"""
    for key in dir(cls):
        if key in cls.methods_overwritable_by_factory and hasattr(cls, key):
            fn = getattr(cls, key)
            original_fn = getattr(field_obj, key, None)
            # use original func, not the wrapper
            if hasattr(fn, "__func__"):
                fn = fn.__func__

            # fix classmethod, prevent injection of self or class
            setattr(
                field_obj,
                key,
                # .__func__ is a workaround for python < 3.10, python >=3.10 works without
                staticmethod(partial(fn, cls, field_obj, original_fn=original_fn)).__func__,
            )

repack classmethod

repack(field_obj)
PARAMETER DESCRIPTION
field_obj

TYPE: BaseFieldType

Source code in edgy/core/db/fields/factories.py
106
107
108
109
110
111
112
113
114
115
116
117
118
119
@classmethod
def repack(cls, field_obj: BaseFieldType) -> None:
    for key in dir(cls):
        if key in cls.methods_overwritable_by_factory and hasattr(cls, key):
            packed_fn = getattr(field_obj, key, None)
            if packed_fn is not None and hasattr(packed_fn, "func"):
                setattr(
                    field_obj,
                    key,
                    # .__func__ is a workaround for python < 3.10, python >=3.10 works without
                    staticmethod(
                        partial(packed_fn.func, cls, field_obj, **packed_fn.keywords)
                    ).__func__,
                )

get_constraints classmethod

get_constraints(**kwargs)

Returns the propery column type for the field, None for Metafields

PARAMETER DESCRIPTION
**kwargs

TYPE: Any DEFAULT: {}

Source code in edgy/core/db/fields/factories.py
129
130
131
132
@classmethod
def get_constraints(cls, **kwargs: Any) -> Sequence[Any]:
    """Returns the propery column type for the field, None for Metafields"""
    return []

get_column_type classmethod

get_column_type(**kwargs)

Returns the propery column type for the field, None for Metafields

PARAMETER DESCRIPTION
**kwargs

TYPE: Any DEFAULT: {}

Source code in edgy/core/db/fields/factories.py
134
135
136
137
@classmethod
def get_column_type(cls, **kwargs: Any) -> Any:
    """Returns the propery column type for the field, None for Metafields"""
    return None

get_pydantic_type classmethod

get_pydantic_type(**kwargs)

Returns the type for pydantic

PARAMETER DESCRIPTION
**kwargs

TYPE: Any DEFAULT: {}

Source code in edgy/core/db/fields/factories.py
139
140
141
142
@classmethod
def get_pydantic_type(cls, **kwargs: Any) -> Any:
    """Returns the type for pydantic"""
    return cls.field_type

_get_field_cls cached staticmethod

_get_field_cls()
Source code in edgy/core/db/fields/factories.py
144
145
146
147
@staticmethod
@lru_cache(None)
def _get_field_cls(cls: "FieldFactory") -> BaseFieldType:
    return cast(BaseFieldType, type(cls.__name__, cast(Any, cls.field_bases), {}))

__new__

__new__(to, *, through=None, from_fields=(), to_fields=(), **kwargs)
PARAMETER DESCRIPTION
to

TYPE: Union[BaseModelType, str]

through

TYPE: Optional[BaseModelType] DEFAULT: None

from_fields

TYPE: Sequence[str] DEFAULT: ()

to_fields

TYPE: Sequence[str] DEFAULT: ()

**kwargs

TYPE: Any DEFAULT: {}

Source code in edgy/core/db/fields/many_to_many.py
287
288
289
290
291
292
293
294
295
296
297
298
def __new__(  # type: ignore
    cls,
    to: Union["BaseModelType", str],
    *,
    through: Optional["BaseModelType"] = None,
    from_fields: Sequence[str] = (),
    to_fields: Sequence[str] = (),
    **kwargs: Any,
) -> "BaseFieldType":
    return super().__new__(
        cls, to=to, through=through, from_fields=from_fields, to_fields=to_fields, **kwargs
    )

validate classmethod

validate(kwargs)
PARAMETER DESCRIPTION
kwargs

TYPE: dict[str, Any]

Source code in edgy/core/db/fields/many_to_many.py
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
@classmethod
def validate(cls, kwargs: dict[str, Any]) -> None:
    super().validate(kwargs)
    embed_through = kwargs.get("embed_through")
    if embed_through and "__" in embed_through:
        raise FieldDefinitionError('"embed_through" cannot contain "__".')

    for argument in ["null", "on_delete", "on_update"]:
        if kwargs.get(argument):
            terminal.write_warning(
                f"Declaring `{argument}` on a ManyToMany relationship has no effect."
            )
    kwargs["null"] = True
    kwargs["on_delete"] = CASCADE
    kwargs["on_update"] = CASCADE