:py:mod:`core.bones.base` ========================= .. py:module:: core.bones.base .. autoapi-nested-parse:: This module contains the base classes for the bones in ViUR. Bones are the fundamental building blocks of ViUR's data structures, representing the fields and their properties in the entities managed by the framework. The base classes defined in this module are the foundation upon which specific bone types are built, such as string, numeric, and date/time bones. Module Contents --------------- Classes ~~~~~~~ .. autoapisummary:: core.bones.base.ReadFromClientErrorSeverity core.bones.base.ReadFromClientError core.bones.base.UniqueLockMethod core.bones.base.UniqueValue core.bones.base.MultipleConstraints core.bones.base.ComputeMethod core.bones.base.ComputeInterval core.bones.base.Compute core.bones.base.BaseBone Functions ~~~~~~~~~ .. autoapisummary:: core.bones.base.setSystemInitialized core.bones.base.getSystemInitialized Attributes ~~~~~~~~~~ .. autoapisummary:: core.bones.base.__system_initialized .. py:data:: __system_initialized :value: False Initializes the global variable __system_initialized .. py:function:: setSystemInitialized() Sets the global __system_initialized variable to True, indicating that the system is initialized and ready for use. This function should be called once all necessary setup tasks have been completed. It also iterates over all skeleton classes and calls their setSystemInitialized() method. Global variables: __system_initialized: A boolean flag indicating if the system is initialized. .. py:function:: getSystemInitialized() Retrieves the current state of the system initialization by returning the value of the global variable __system_initialized. .. py:class:: ReadFromClientErrorSeverity Bases: :py:obj:`enum.Enum` ReadFromClientErrorSeverity is an enumeration that represents the severity levels of errors that can occur while reading data from the client. .. py:attribute:: NotSet :value: 0 No error occurred .. py:attribute:: InvalidatesOther :value: 1 The data is valid, for this bone, but in relation to other invalid .. py:attribute:: Empty :value: 2 The data is empty, but the bone requires a value .. py:attribute:: Invalid :value: 3 The data is invalid, but the bone requires a value .. py:class:: ReadFromClientError The ReadFromClientError class represents an error that occurs while reading data from the client. This class is used to store information about the error, including its severity, an error message, the field path where the error occurred, and a list of invalidated fields. .. py:attribute:: severity :type: ReadFromClientErrorSeverity A ReadFromClientErrorSeverity enumeration value representing the severity of the error. .. py:attribute:: errorMessage :type: str A string containing a human-readable error message describing the issue. .. py:attribute:: fieldPath :type: list[str] A list of strings representing the path to the field where the error occurred. .. py:attribute:: invalidatedFields :type: list[str] A list of strings containing the names of invalidated fields, if any. .. py:class:: UniqueLockMethod Bases: :py:obj:`enum.Enum` UniqueLockMethod is an enumeration that represents different locking methods for unique constraints on bones. This is used to specify how the uniqueness of a value or a set of values should be enforced. .. py:attribute:: SameValue :value: 1 Lock this value so that there is only one entry, or lock each value individually if the bone is multiple. .. py:attribute:: SameSet :value: 2 Lock the same set of entries (including duplicates) regardless of their order. .. py:attribute:: SameList :value: 3 Lock the same set of entries (including duplicates) in a specific order. .. py:class:: UniqueValue The UniqueValue class represents a unique constraint on a bone, ensuring that it must have a different value for each entry. This class is used to store information about the unique constraint, such as the locking method, whether to lock empty values, and an error message to display to the user if the requested value is already taken. .. py:attribute:: method :type: UniqueLockMethod A UniqueLockMethod enumeration value specifying how to handle multiple values for bones with multiple=True. .. py:attribute:: lockEmpty :type: bool A boolean value indicating if empty values ("", 0) should be locked. If False, empty values are not locked, which is needed if a field is unique but not required. .. py:attribute:: message :type: str A string containing an error message displayed to the user if the requested value is already taken. .. py:class:: MultipleConstraints The MultipleConstraints class is used to define constraints on multiple bones, such as the minimum and maximum number of entries allowed and whether value duplicates are allowed. .. py:attribute:: min :type: int :value: 0 An integer representing the lower bound of how many entries can be submitted (default: 0). .. py:attribute:: max :type: int :value: 0 An integer representing the upper bound of how many entries can be submitted (default: 0 = unlimited). .. py:attribute:: duplicates :type: bool :value: False A boolean indicating if the same value can be used multiple times (default: False). .. py:class:: ComputeMethod Bases: :py:obj:`enum.Enum` Generic enumeration. Derive from this class to define new enumerations. .. py:attribute:: Always :value: 0 .. py:attribute:: Lifetime :value: 1 .. py:attribute:: Once :value: 2 .. py:attribute:: OnWrite :value: 3 .. py:class:: ComputeInterval .. py:attribute:: method :type: ComputeMethod .. py:attribute:: lifetime :type: datetime.timedelta .. py:class:: Compute .. py:attribute:: fn :type: callable .. py:attribute:: interval :type: ComputeInterval .. py:attribute:: raw :type: bool :value: True .. py:class:: BaseBone(*, compute = None, defaultValue = None, descr = '', getEmptyValueFunc = None, indexed = True, isEmptyFunc = None, languages = None, multiple = False, params = None, readOnly = None, required = False, searchable = False, type_suffix = '', unique = None, vfunc = None, visible = True) Bases: :py:obj:`object` The BaseBone class serves as the base class for all bone types in the ViUR framework. It defines the core functionality and properties that all bones should implement. :param descr: Textual, human-readable description of that bone. Will be translated. :param defaultValue: If set, this bone will be preinitialized with this value :param required: If True, the user must enter a valid value for this bone (the viur.core refuses to save the skeleton otherwise). If a list/tuple of languages (strings) is provided, these language must be entered. :param multiple: If True, multiple values can be given. (ie. n:m relations instead of n:1) :param searchable: If True, this bone will be included in the fulltext search. Can be used without the need of also been indexed. :param type_suffix: Allows to specify an optional suffix for the bone-type, for bone customization :param vfunc: If given, a callable validating the user-supplied value for this bone. This callable must return None if the value is valid, a String containing an meaningful error-message for the user otherwise. :param readOnly: If True, the user is unable to change the value of this bone. If a value for this bone is given along the POST-Request during Add/Edit, this value will be ignored. Its still possible for the developer to modify this value by assigning skel.bone.value. :param visible: If False, the value of this bone should be hidden from the user. This does *not* protect the value from being exposed in a template, nor from being transferred to the client (ie to the admin or as hidden-value in html-form) :param compute: If set, the bone's value will be computed in the given method. .. NOTE:: The kwarg 'multiple' is not supported by all bones Initializes a new Bone. .. py:attribute:: type :value: 'hidden' .. py:attribute:: isClonedInstance :value: False .. py:attribute:: skel_cls Skeleton class to which this bone instance belongs .. py:attribute:: name Name of this bone (attribute name in the skeletons containing this bone) .. py:method:: __set_name__(owner, name) .. py:method:: setSystemInitialized() Can be overridden to initialize properties that depend on the Skeleton system being initialized .. py:method:: isInvalid(value) Checks if the current value of the bone in the given skeleton is invalid. Returns None if the value would be valid for this bone, an error-message otherwise. .. py:method:: isEmpty(value) Check if the given single value represents the "empty" value. This usually is the empty string, 0 or False. .. warning:: isEmpty takes precedence over isInvalid! The empty value is always valid - unless the bone is required. But even then the empty value will be reflected back to the client. .. warning:: value might be the string/object received from the user (untrusted input!) or the value returned by get .. py:method:: getDefaultValue(skeletonInstance) Retrieves the default value for the bone. This method is called by the framework to obtain the default value of a bone when no value is provided. Derived bone classes can overwrite this method to implement their own logic for providing a default value. :return: The default value of the bone, which can be of any data type. .. py:method:: getEmptyValue() Returns the value representing an empty field for this bone. This might be the empty string for str/text Bones, Zero for numeric bones etc. .. py:method:: __setattr__(key, value) Custom attribute setter for the BaseBone class. This method is used to ensure that certain bone attributes, such as 'multiple', are only set once during the bone's lifetime. Derived bone classes should not need to overwrite this method unless they have additional attributes with similar constraints. :param key: A string representing the attribute name. :param value: The value to be assigned to the attribute. :raises AttributeError: If a protected attribute is attempted to be modified after its initial assignment. .. py:method:: collectRawClientData(name, data, multiple, languages, collectSubfields) Collects raw client data for the bone and returns it in a dictionary. This method is called by the framework to gather raw data from the client, such as form data or data from a request. Derived bone classes should overwrite this method to implement their own logic for collecting raw data. :param name: A string representing the bone's name. :param data: A dictionary containing the raw data from the client. :param multiple: A boolean indicating whether the bone supports multiple values. :param languages: An optional list of strings representing the supported languages (default: None). :param collectSubfields: A boolean indicating whether to collect data for subfields (default: False). :return: A dictionary containing the collected raw client data. .. py:method:: parseSubfieldsFromClient() Determines whether the function should parse subfields submitted by the client. Set to True only when expecting a list of dictionaries to be transmitted. .. py:method:: singleValueFromClient(value, skel, bone_name, client_data) Load a single value from a client :param value: The single value which should be loaded. :param skel: The SkeletonInstance where the value should be loaded into. :param bone_name: The bone name of this bone in the SkeletonInstance. :param client_data: The data taken from the client, a dictionary with usually bone names as key :return: A tuple. If the value is valid, the first element is the parsed value and the second is None. If the value is invalid or not parseable, the first element is a empty value and the second a list of *ReadFromClientError*. .. py:method:: fromClient(skel, name, data) Reads a value from the client and stores it in the skeleton instance if it is valid for the bone. This function reads a value from the client and processes it according to the bone's configuration. If the value is valid for the bone, it stores the value in the skeleton instance and returns None. Otherwise, the previous value remains unchanged, and a list of ReadFromClientError objects is returned. :param skel: A SkeletonInstance object where the values should be loaded. :param name: A string representing the bone's name. :param data: A dictionary containing the raw data from the client. :return: None if no errors occurred, otherwise a list of ReadFromClientError objects. .. py:method:: _get_single_destinct_hash(value) Returns a distinct hash value for a single entry of this bone. The returned value must be hashable. .. py:method:: _get_destinct_hash(value) Returns a distinct hash value for this bone. The returned value must be hashable. .. py:method:: _validate_multiple_contraints(constraints, skel, name) Validates the value of a bone against its multiple constraints and returns a list of ReadFromClientError objects for each violation, such as too many items or duplicates. :param constraints: The MultipleConstraints definition to apply. :param skel: A SkeletonInstance object where the values should be validated. :param name: A string representing the bone's name. :return: A list of ReadFromClientError objects for each constraint violation. .. py:method:: singleValueSerialize(value, skel, name, parentIndexed) Serializes a single value of the bone for storage in the database. Derived bone classes should overwrite this method to implement their own logic for serializing single values. The serialized value should be suitable for storage in the database. .. py:method:: serialize(skel, name, parentIndexed) Serializes this bone into a format that can be written into the datastore. :param skel: A SkeletonInstance object containing the values to be serialized. :param name: A string representing the property name of the bone in its Skeleton (not the description). :param parentIndexed: A boolean indicating whether the parent bone is indexed. :return: A boolean indicating whether the serialization was successful. .. py:method:: singleValueUnserialize(val) Unserializes a single value of the bone from the stored database value. Derived bone classes should overwrite this method to implement their own logic for unserializing single values. The unserialized value should be suitable for use in the application logic. .. py:method:: unserialize(skel, name) Deserialize bone data from the datastore and populate the bone with the deserialized values. This function is the inverse of the serialize function. It converts data from the datastore into a format that can be used by the bones in the skeleton. :param skel: A SkeletonInstance object containing the values to be deserialized. :param name: The property name of the bone in its Skeleton (not the description). :returns: True if deserialization is successful, False otherwise. .. py:method:: delete(skel, name) Like postDeletedHandler, but runs inside the transaction .. py:method:: buildDBFilter(name, skel, dbFilter, rawFilter, prefix = None) Parses the searchfilter a client specified in his Request into something understood by the datastore. This function must: * - Ignore all filters not targeting this bone * - Safely handle malformed data in rawFilter (this parameter is directly controlled by the client) :param name: The property-name this bone has in its Skeleton (not the description!) :param skel: The :class:`viur.core.db.Query` this bone is part of :param dbFilter: The current :class:`viur.core.db.Query` instance the filters should be applied to :param rawFilter: The dictionary of filters the client wants to have applied :returns: The modified :class:`viur.core.db.Query` .. py:method:: buildDBSort(name, skel, dbFilter, rawFilter) Same as buildDBFilter, but this time its not about filtering the results, but by sorting them. Again: rawFilter is controlled by the client, so you *must* expect and safely handle malformed data! :param name: The property-name this bone has in its Skeleton (not the description!) :param skel: The :class:`viur.core.skeleton.Skeleton` instance this bone is part of :param dbFilter: The current :class:`viur.core.db.Query` instance the filters should be applied to :param rawFilter: The dictionary of filters the client wants to have applied :returns: The modified :class:`viur.core.db.Query`, None if the query is unsatisfiable. .. py:method:: _hashValueForUniquePropertyIndex(value) Generates a hash of the given value for creating unique property indexes. This method is called by the framework to create a consistent hash representation of a value for constructing unique property indexes. Derived bone classes should overwrite this method to implement their own logic for hashing values. :param value: The value to be hashed, which can be a string, integer, or a float. :return: A list containing a string representation of the hashed value. If the bone is multiple, the list may contain more than one hashed value. .. py:method:: getUniquePropertyIndexValues(skel, name) Returns a list of hashes for the current value(s) of a bone in the skeleton, used for storing in the unique property value index. :param skel: A SkeletonInstance object representing the current skeleton. :param name: The property-name of the bone in the skeleton for which the unique property index values are required (not the description!). :return: A list of strings representing the hashed values for the current bone value(s) in the skeleton. If the bone has no value, an empty list is returned. .. py:method:: getReferencedBlobs(skel, name) Returns a set of blob keys referenced from this bone .. py:method:: performMagic(valuesCache, name, isAdd) This function applies "magically" functionality which f.e. inserts the current Date or the current user. :param isAdd: Signals wherever this is an add or edit operation. .. py:method:: postSavedHandler(skel, boneName, key) Can be overridden to perform further actions after the main entity has been written. :param boneName: Name of this bone :param skel: The skeleton this bone belongs to :param key: The (new?) Database Key we've written to .. py:method:: postDeletedHandler(skel, boneName, key) Can be overridden to perform further actions after the main entity has been deleted. :param skel: The skeleton this bone belongs to :param boneName: Name of this bone :param key: The old Database Key of the entity we've deleted .. py:method:: refresh(skel, boneName) Refresh all values we might have cached from other entities. .. py:method:: mergeFrom(valuesCache, boneName, otherSkel) Merges the values from another skeleton instance into the current instance, given that the bone types match. :param valuesCache: A dictionary containing the cached values for each bone in the skeleton. :param boneName: The property-name of the bone in the skeleton whose values are to be merged. :param otherSkel: A SkeletonInstance object representing the other skeleton from which the values are to be merged. This function clones the values from the specified bone in the other skeleton instance into the current instance, provided that the bone types match. If the bone types do not match, a warning is logged, and the merge is ignored. If the bone in the other skeleton has no value, the function returns without performing any merge operation. .. py:method:: setBoneValue(skel, boneName, value, append, language = None) Sets the value of a bone in a skeleton instance, with optional support for appending and language-specific values. Sanity checks are being performed. :param skel: The SkeletonInstance object representing the skeleton to which the bone belongs. :param boneName: The property-name of the bone in the skeleton whose value should be set or modified. :param value: The value to be assigned. Its type depends on the type of the bone. :param append: If True, the given value is appended to the bone's values instead of replacing it. Only supported for bones with multiple=True. :param language: The language code for which the value should be set or appended, if the bone supports languages. :return: A boolean indicating whether the operation was successful or not. This function sets or modifies the value of a bone in a skeleton instance, performing sanity checks to ensure the value is valid. If the value is invalid, no modification occurs. The function supports appending values to bones with multiple=True and setting or appending language-specific values for bones that support languages. .. py:method:: getSearchTags(skel, name) Returns a set of strings as search index for this bone. This function extracts a set of search tags from the given bone's value in the skeleton instance. The resulting set can be used for indexing or searching purposes. :param skel: The skeleton instance where the values should be loaded from. This is an instance of a class derived from `viur.core.skeleton.SkeletonInstance`. :param name: The name of the bone, which is a string representing the key for the bone in the skeleton. This should correspond to an existing bone in the skeleton instance. :return: A set of strings, extracted from the bone value. If the bone value doesn't have any searchable content, an empty set is returned. .. py:method:: iter_bone_value(skel, name) Yield all values from the Skeleton related to this bone instance. This method handles multiple/languages cases, which could save a lot of if/elifs. It always yields a triplet: index, language, value. Where index is the index (int) of a value inside a multiple bone, language is the language (str) of a multi-language-bone, and value is the value inside this container. index or language is None if the bone is single or not multi-lang. This function can be used to conveniently iterate through all the values of a specific bone in a skeleton instance, taking into account multiple and multi-language bones. :param skel: The skeleton instance where the values should be loaded from. This is an instance of a class derived from `viur.core.skeleton.SkeletonInstance`. :param name: The name of the bone, which is a string representing the key for the bone in the skeleton. This should correspond to an existing bone in the skeleton instance. :return: A generator which yields triplets (index, language, value), where index is the index of a value inside a multiple bone, language is the language of a multi-language bone, and value is the value inside this container. index or language is None if the bone is single or not multi-lang. .. py:method:: _compute(skel, bone_name) Performs the evaluation of a bone configured as compute .. py:method:: structure() Describes the bone and its settings as an JSON-serializable dict. This function has to be implemented for subsequent, specialized bone types.