Example #1
0
def adjust_through_many_to_many_model(
        model: Type["Model"], child: Type["Model"],
        model_field: Type[ManyToManyField]) -> None:
    model_field.through.Meta.model_fields[model.get_name()] = ForeignKey(
        model, real_name=model.get_name(), ondelete="CASCADE")
    model_field.through.Meta.model_fields[child.get_name()] = ForeignKey(
        child, real_name=child.get_name(), ondelete="CASCADE")

    create_and_append_m2m_fk(model, model_field)
    create_and_append_m2m_fk(child, model_field)

    create_pydantic_field(model.get_name(), model, model_field)
    create_pydantic_field(child.get_name(), child, model_field)
Example #2
0
def register_reverse_model_fields(
        model_field: Type["ForeignKeyField"]) -> None:
    """
    Registers reverse ForeignKey field on related model.
    By default it's name.lower()+'s' of the model on which relation is defined.

    But if the related_model name is provided it's registered with that name.
    Autogenerated reverse fields also set related_name to the original field name.

    :param model_field: original relation ForeignKey field
    :type model_field: relation Field
    """
    related_name = model_field.get_related_name()
    if issubclass(model_field, ManyToManyField):
        model_field.to.Meta.model_fields[related_name] = ManyToMany(
            model_field.owner,
            through=model_field.through,
            name=related_name,
            virtual=True,
            related_name=model_field.name,
            owner=model_field.to,
            self_reference=model_field.self_reference,
            self_reference_primary=model_field.self_reference_primary,
        )
        # register foreign keys on through model
        adjust_through_many_to_many_model(model_field=model_field)
    else:
        model_field.to.Meta.model_fields[related_name] = ForeignKey(
            model_field.owner,
            real_name=related_name,
            virtual=True,
            related_name=model_field.name,
            owner=model_field.to,
            self_reference=model_field.self_reference,
        )
Example #3
0
def adjust_through_many_to_many_model(
        model_field: Type[ManyToManyField]) -> None:
    """
    Registers m2m relation on through model.
    Sets ormar.ForeignKey from through model to both child and parent models.
    Sets sqlalchemy.ForeignKey to both child and parent models.
    Sets pydantic fields with child and parent model types.

    :param model_field: relation field defined in parent model
    :type model_field: ManyToManyField
    """
    parent_name = model_field.default_target_field_name()
    child_name = model_field.default_source_field_name()

    model_field.through.Meta.model_fields[parent_name] = ForeignKey(
        model_field.to,
        real_name=parent_name,
        ondelete="CASCADE",
        owner=model_field.through,
    )
    model_field.through.Meta.model_fields[child_name] = ForeignKey(
        model_field.owner,
        real_name=child_name,
        ondelete="CASCADE",
        owner=model_field.through,
    )

    create_and_append_m2m_fk(model=model_field.to,
                             model_field=model_field,
                             field_name=parent_name)
    create_and_append_m2m_fk(model=model_field.owner,
                             model_field=model_field,
                             field_name=child_name)

    create_pydantic_field(parent_name, model_field.to, model_field)
    create_pydantic_field(child_name, model_field.owner, model_field)
Example #4
0
def register_reverse_model_fields(
    model: Type["Model"],
    child: Type["Model"],
    child_model_name: str,
    model_field: Type["ForeignKeyField"],
) -> None:
    if issubclass(model_field, ManyToManyField):
        model.Meta.model_fields[child_model_name] = ManyToMany(
            child,
            through=model_field.through,
            name=child_model_name,
            virtual=True)
        # register foreign keys on through model
        adjust_through_many_to_many_model(model, child, model_field)
    else:
        model.Meta.model_fields[child_model_name] = ForeignKey(
            child, real_name=child_model_name, virtual=True)
Example #5
0
def register_reverse_model_fields(model_field: "ForeignKeyField") -> None:
    """
    Registers reverse ForeignKey field on related model.
    By default it's name.lower()+'s' of the model on which relation is defined.

    But if the related_model name is provided it's registered with that name.
    Autogenerated reverse fields also set related_name to the original field name.

    :param model_field: original relation ForeignKey field
    :type model_field: relation Field
    """
    related_name = model_field.get_related_name()
    if model_field.is_multi:
        model_field.to.Meta.model_fields[related_name] = ManyToMany(  # type: ignore
            model_field.owner,
            through=model_field.through,
            name=related_name,
            virtual=True,
            related_name=model_field.name,
            owner=model_field.to,
            self_reference=model_field.self_reference,
            self_reference_primary=model_field.self_reference_primary,
            orders_by=model_field.related_orders_by,
            skip_field=model_field.skip_reverse,
            through_relation_name=model_field.through_reverse_relation_name,
            through_reverse_relation_name=model_field.through_relation_name,
        )
        # register foreign keys on through model
        model_field = cast("ManyToManyField", model_field)
        register_through_shortcut_fields(model_field=model_field)
        adjust_through_many_to_many_model(model_field=model_field)
    else:
        model_field.to.Meta.model_fields[related_name] = ForeignKey(  # type: ignore
            model_field.owner,
            real_name=related_name,
            virtual=True,
            related_name=model_field.name,
            owner=model_field.to,
            self_reference=model_field.self_reference,
            orders_by=model_field.related_orders_by,
            skip_field=model_field.skip_reverse,
        )