Skip to content

ForeignKey class

saffier.ForeignKey

ForeignKey(to, null=False, on_delete=RESTRICT, on_update=CASCADE, related_name=None, **kwargs)

Bases: Field

ForeignKey field object

PARAMETER DESCRIPTION
to

TYPE: Type[Model]

null

TYPE: bool DEFAULT: False

on_delete

TYPE: str DEFAULT: RESTRICT

on_update

TYPE: str DEFAULT: CASCADE

related_name

TYPE: Optional[str] DEFAULT: None

**kwargs

TYPE: Any DEFAULT: {}

Source code in saffier/core/db/fields/base.py
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
def __init__(
    self,
    to: typing.Type["Model"],
    null: bool = False,
    on_delete: str = RESTRICT,
    on_update: str = CASCADE,
    related_name: typing.Optional[str] = None,
    **kwargs: Any,
):
    assert on_delete is not None, "on_delete must not be null."

    if on_delete == SET_NULL and not null:
        raise AssertionError("When SET_NULL is enabled, null must be True.")

    if on_update and (on_update == SET_NULL and not null):
        raise AssertionError("When SET_NULL is enabled, null must be True.")

    super().__init__(null=null)
    self.to = to
    self.on_delete = on_delete
    self.on_update = on_update or CASCADE
    self.related_name = related_name

server_default instance-attribute

server_default = pop('server_default', None)

null instance-attribute

null = get('null', False)

default_value instance-attribute

default_value = get('default', None)

primary_key instance-attribute

primary_key = primary_key

index instance-attribute

index = index

unique instance-attribute

unique = unique

validator instance-attribute

validator = get_validator(**kwargs)

comment instance-attribute

comment = get('comment', None)

owner instance-attribute

owner = pop('owner', None)

server_onupdate instance-attribute

server_onupdate = pop('server_onupdate', None)

autoincrement instance-attribute

autoincrement = pop('autoincrement', False)

secret instance-attribute

secret = pop('secret', False)

to instance-attribute

to = to

on_delete instance-attribute

on_delete = on_delete

on_update instance-attribute

on_update = on_update or CASCADE

related_name instance-attribute

related_name = related_name

target property

target

ForeignKeyValidator

ForeignKeyValidator(*, title='', description='', help_text='', default=NO_DEFAULT, null=False, read_only=False, **kwargs)

Bases: SaffierField

PARAMETER DESCRIPTION
title

TYPE: str DEFAULT: ''

description

TYPE: str DEFAULT: ''

help_text

TYPE: str DEFAULT: ''

default

TYPE: Any DEFAULT: NO_DEFAULT

null

TYPE: bool DEFAULT: False

read_only

TYPE: bool DEFAULT: False

**kwargs

TYPE: Any DEFAULT: {}

Source code in saffier/core/db/fields/_internal.py
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def __init__(
    self,
    *,
    title: str = "",
    description: str = "",
    help_text: str = "",
    default: typing.Any = NO_DEFAULT,
    null: bool = False,
    read_only: bool = False,
    **kwargs: typing.Any,
) -> None:
    super().__init__(**kwargs)
    if null and default is NO_DEFAULT:
        default = None

    if default is not NO_DEFAULT:
        self.default = default

    self.null = null
    self.read_only = read_only
    self.title = title
    self.description = description
    self.help_text = help_text

error_messages class-attribute instance-attribute

error_messages = {}

default instance-attribute

default = default

null instance-attribute

null = null

read_only instance-attribute

read_only = read_only

title instance-attribute

title = title

description instance-attribute

description = description

help_text instance-attribute

help_text = help_text

__hash__

__hash__()
Source code in saffier/core/datastructures.py
19
20
21
22
23
24
25
26
27
def __hash__(self) -> Any:
    values: Any = {}
    for key, value in self.__dict__.items():
        values[key] = None
        if isinstance(value, (list, set)):
            values[key] = tuple(value)
        else:
            values[key] = value
    return hash((type(self),) + tuple(values))

validate_or_error

validate_or_error(value)
PARAMETER DESCRIPTION
value

TYPE: Any

Source code in saffier/core/db/fields/_internal.py
59
60
61
62
63
64
def validate_or_error(self, value: typing.Any) -> ValidationResult:
    try:
        value = self.check(value)
    except ValidationError as error:
        return ValidationResult(value=None, error=error)
    return ValidationResult(value=value, error=None)

has_default

has_default()
Source code in saffier/core/db/fields/_internal.py
66
67
def has_default(self) -> bool:
    return hasattr(self, "default")

validation_error

validation_error(code, value=None)
PARAMETER DESCRIPTION
code

TYPE: str

value

TYPE: Optional[Any] DEFAULT: None

Source code in saffier/core/db/fields/_internal.py
69
70
71
72
73
def validation_error(
    self, code: str, value: typing.Optional[typing.Any] = None
) -> ValidationError:
    text = self.get_error_message(code)
    return ValidationError(text=text, code=code)

get_error_message

get_error_message(code)
PARAMETER DESCRIPTION
code

TYPE: str

Source code in saffier/core/db/fields/_internal.py
75
76
def get_error_message(self, code: str) -> str:
    return self.error_messages[code].format(**self.__dict__)

get_default_value

get_default_value()
Source code in saffier/core/db/fields/_internal.py
78
79
80
81
82
def get_default_value(self) -> typing.Any:
    default = getattr(self, "default", None)
    if callable(default):
        return default()
    return default

check

check(value)
PARAMETER DESCRIPTION
value

TYPE: Any

Source code in saffier/core/db/fields/base.py
270
271
def check(self, value: typing.Any) -> typing.Any:
    return value.pk

get_column_type

get_column_type()
Source code in saffier/core/db/fields/base.py
91
92
def get_column_type(self) -> sqlalchemy.types.TypeEngine:
    raise NotImplementedError()  # pragma: no cover

get_constraints

get_constraints()
Source code in saffier/core/db/fields/base.py
94
95
def get_constraints(self) -> typing.Any:
    return []

raise_for_non_default

raise_for_non_default(default, server_default)
PARAMETER DESCRIPTION
default

TYPE: Any

server_default

TYPE: Any

Source code in saffier/core/db/fields/base.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
def raise_for_non_default(self, default: typing.Any, server_default: typing.Any) -> typing.Any:
    has_default: bool = True
    has_server_default: bool = True

    if default is None or default is False:
        has_default = False
    if server_default is None or server_default is False:
        has_server_default = False

    if (
        not isinstance(self, (IntegerField, BigIntegerField))
        and not has_default
        and not has_server_default
    ):
        raise ValueError(
            "Primary keys other then IntegerField and BigIntegerField, must provide a default or a server_default."
        )

get_validator

get_validator(**kwargs)
PARAMETER DESCRIPTION
**kwargs

TYPE: Any DEFAULT: {}

Source code in saffier/core/db/fields/base.py
305
306
def get_validator(self, **kwargs: typing.Any) -> SaffierField:
    return self.ForeignKeyValidator(**kwargs)

get_column

get_column(name)
PARAMETER DESCRIPTION
name

TYPE: str

Source code in saffier/core/db/fields/base.py
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
def get_column(self, name: str) -> sqlalchemy.Column:
    target = self.target
    to_field = target.fields[target.pkname]

    column_type = to_field.get_column_type()
    constraints = [
        sqlalchemy.schema.ForeignKey(
            f"{target.meta.tablename}.{target.pkname}",
            ondelete=self.on_delete,
            onupdate=self.on_update,
            name=f"fk_{self.owner.meta.tablename}_{target.meta.tablename}"
            f"_{target.pkname}_{name}",
        )
    ]
    return sqlalchemy.Column(name, column_type, *constraints, nullable=self.null)

expand_relationship

expand_relationship(value)
PARAMETER DESCRIPTION
value

TYPE: Any

Source code in saffier/core/db/fields/base.py
324
325
326
327
328
def expand_relationship(self, value: typing.Any) -> typing.Any:
    target = self.target
    if isinstance(value, target):
        return value
    return target(pk=value)