Skip to content

Properties

immmdreza edited this page Jun 5, 2022 · 2 revisions

Learn about Properties

As you may already know, every SJD model has a set of properties. This properties inform the package about type of data you gonna put inside it.

Here you'll learn more about available properties that you can use inside your model.

Available types are those are available in JSON:

  • String
  • Integer
  • Float
  • Boolean
  • List ( or Array )
  • Object ( another JSON object )

Access

You can access all of properties in one place like this:

from sjd import properties as props

Options

Every property has a set of options that you can modify based on your case.

  • init: Indicates if this property should be passed to model's __init__ function or not ( If there's any __init__ function defined ).
  • json_property_name: The property name inside json file. Defaults to attribute name.
  • required: Indicates if this property should always be available while serializing or deserializing object.

Explain

Here you can find a brief explanation about all properties and their use case.

props.string()

For python str fields.

Required Parameters: This method has no required parameter.

class Model(TEntity):
    # ---- sniff ----

    string_field = props.string()

    # ---- sniff ----

props.integer()

For python int fields.

Required Parameters: This method has no required parameter.

class Model(TEntity):
    # ---- sniff ----

    integer_field = props.integer()

    # ---- sniff ----

props.double()

For python float fields. ( Why i named it like this then? )

Required Parameters: This method has no required parameter.

class Model(TEntity):
    # ---- sniff ----

    float_field = props.double()

    # ---- sniff ----

props.boolean()

For python bool fields.

Required Parameters: This method has no required parameter.

class Model(TEntity):
    # ---- sniff ----

    bool_field = props.boolean()

    # ---- sniff ----

props.array()

For python list fields. You can use this to store a list of any valid type. Note that, if wanna use a list of other models inside your model, it should be a subclass of EmbeddedEntity.

Required Parameters:

  • of_typed: You should pass the type of objects this field should store.
class OtherModel(EmbeddedEntity):
    # ---- sniff ----

class Model(TEntity):
    # ---- sniff ----

    str_list_field = props.array(str)
    other_models_field = props.array(OtherModel)
    ...

    # ---- sniff ----

props.entity()

For other python model inside your model. Note that, the model should be a subclass of EmbeddedEntity.

Required Parameters:

  • of_typed: You should pass the type of object this field should store.
class OtherModel(EmbeddedEntity):
    # ---- sniff ----
    
class Model(TEntity):
    # ---- sniff ----

    other_model_field = props.entity(OtherModel)
    ...

    # ---- sniff ----

props.from_entity()

This is for virtual properties. (Read more)

To use other models inside your model virtually ( or lazily ). It's like props.entity but the target entity is saved inside another collection and it's not included inside main entity unless you ask for it. Note that, the type your gonna use here should be a subclass of Entity.

You can consider this as a one-to-one relation between two collections.

Required Parameters:

  • of_typed: You should pass the type of object this field should store.
  • refers_to: The name of reference property inside other entity.
class OtherModel(Entity):
    # ---- sniff ----

    model_id = props.reference()
    
class Model(TEntity):
    # ---- sniff ----

    other_model_field = props.from_entity(OtherModel, "model_id")
    ...

    # ---- sniff ----

props.from_entities()

It's like props.from_entity(), for a list of other model.

You can consider this as a one-to-many relation.

Required Parameters:

  • of_typed: You should pass the type of objects this field should store.
  • refers_to: The name of reference property inside other entity.
class OtherModel(Entity):
    # ---- sniff ----

    model_id = props.reference()
    
class Model(TEntity):
    # ---- sniff ----

    other_models_field = props.from_entities(OtherModel, "model_id")
    ...

    # ---- sniff ----

props.reference()

This property should be inside models that are virtually used inside another model.

See props.from_entity().

Required Parameters: This method has no required parameter (nor optional).

Optional properties

Normally when you pass required parameter as False, the field is optional. but for the sake of type hinting, you have other ways to mark your property as optional.

props.optional()

Wrap your property with this and now it's T | None, instead of T.

optional_str = props.optional(props.string())

TProperty.optional()

Or you can simply call optional() method of any property.

optional_str = props.string().optional()

__init__ Method

It's super common that we use __init__ method inside our model, to make things simpler.

But when you're going to use it here, you should consider things.

  1. USE __json_init__ = True.
  2. Namings in props definition, inside __init__ method's parameters and inside the body of __init__, SHOULD be the same.
  3. Set default value for optional properties.
  4. If you're using other parameters for __init__, set default value for them too.
class Model(TEntity):

    __json_init__ = True

    name = props.string()
    family_name = props.string().optional()

    def __init__(self, name: str, family_name: str | None = None, other_blah = default):
        self.name = name
        self.family_name = family_name

        # blah

Now it's a good init!

props.auto_collect() [decorator]

Instead of things we did above, we could simply use props.auto_collect() decorator on our Model.

@props.auto_collect(ignore_params=["other_blah"])
class Model(TEntity):
    def __init__(self, name: str, family_name: str | None = None, other_blah = default):
        self.name = name
        self.family_name = family_name

        # blah

Consideration

  1. Type hints are required! ( : str, : str | None, ... )
  2. Use valid types as type hint.
  3. Add params that are not properties, inside ignore_params of auto_collect.
  4. Watch for namings just like above.

FAQ

  1. Should i do something especial when i wanna use __init__ inside my model?

    Yes, see __init__ Method.

Clone this wiki locally