core.bones

Submodules

Package Contents

Classes

BaseBone

ReadFromClientError

ReadFromClientErrorSeverity

Generic enumeration.

UniqueValue

UniqueLockMethod

Generic enumeration.

MultipleConstraints

BooleanBone

CaptchaBone

ColorBone

CredentialBone

A bone for storing credentials.

DateBone

EmailBone

FileBone

KeyBone

NumericBone

Holds numeric values.

PasswordBone

A bone holding passwords.

RandomSliceBone

Simulates the orderby=random from SQL.

RawBone

Stores it's data without applying any pre/post-processing or filtering. Can be used to store non-html content.

RecordBone

RelationalBone

This is our magic class implementing relations.

RelationalConsistency

Generic enumeration.

SelectCountryBone

SelectBone

SortIndexBone

SpatialBone

Allows to query by Elements close to a given position.

StringBone

TextBone

TreeLeafBone

TreeNodeBone

UserBone

class core.bones.BaseBone(*, defaultValue: Any = None, descr: str = '', getEmptyValueFunc: callable = None, indexed: bool = True, isEmptyFunc: callable = None, languages: None | List[str] = None, multiple: bool | MultipleConstraints = False, params: Dict = None, readOnly: bool = False, required: bool | List[str] | Tuple[str] = False, searchable: bool = False, unique: None | UniqueValue = None, vfunc: callable = None, visible: bool = True)

Bases: object

type = hidden
isClonedInstance = False
setSystemInitialized()

Can be overridden to initialize properties that depend on the Skeleton system being initialized

isInvalid(value)

Returns None if the value would be valid for this bone, an error-message otherwise.

isEmpty(rawValue: Any) bool

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: rawValue might be the string/object received from the user (untrusted input!) or the value

returned by get

getDefaultValue(skeletonInstance)
getEmptyValue() Any

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.

__setattr__(key, value)

Implement setattr(self, name, value).

collectRawClientData(name, data, multiple, languages, collectSubfields)
parseSubfieldsFromClient() bool

Whenever this request should try to parse subfields submitted from the client. Set only to true if you expect a list of dicts to be transmitted

singleValueFromClient(value, skel, name, origData)
fromClient(skel: SkeletonInstance, name: str, data: dict) None | List[ReadFromClientError]

Reads a value from the client.

If this value is valid for this bone, store this value and return None. Otherwise our previous value is left unchanged and an error-message is returned.

Parameters:
  • skel – The skeleton instance where the values should be loaded.

  • name – Our name in the skeleton

  • data – User-supplied request-data

Returns:

None or a list of errors

validateMultipleConstraints(skel: SkeletonInstance, name: str) List[ReadFromClientError]

Validates our value against our multiple constrains. Returns a ReadFromClientError for each violation (eg. too many items and duplicates)

singleValueSerialize(value, skel: SkeletonInstance, name: str, parentIndexed: bool)
serialize(skel: SkeletonInstance, name: str, parentIndexed: bool) bool

Serializes this bone into something we can write into the datastore.

Parameters:

name – The property-name this bone has in its Skeleton (not the description!)

singleValueUnserialize(val)
unserialize(skel: viur.core.skeleton.SkeletonInstance, name: str) bool

Inverse of serialize. Evaluates whats read from the datastore and populates this bone accordingly.

Parameters:

name – The property-name this bone has in its Skeleton (not the description!)

delete(skel: viur.core.skeleton.SkeletonInstance, name: str)

Like postDeletedHandler, but runs inside the transaction

buildDBFilter(name: str, skel: viur.core.skeleton.SkeletonInstance, dbFilter: viur.core.db.Query, rawFilter: Dict, prefix: str | None = None) viur.core.db.Query

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)

Parameters:
  • name – The property-name this bone has in its Skeleton (not the description!)

  • skel – The viur.core.db.Query this bone is part of

  • dbFilter – The current viur.core.db.Query instance the filters should be applied to

  • rawFilter – The dictionary of filters the client wants to have applied

Returns:

The modified viur.core.db.Query

buildDBSort(name: str, skel: viur.core.skeleton.SkeletonInstance, dbFilter: viur.core.db.Query, rawFilter: Dict) viur.core.db.Query | None

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 hande malformed data!

Parameters:
  • name – The property-name this bone has in its Skeleton (not the description!)

  • skel – The viur.core.skeleton.Skeleton instance this bone is part of

  • dbFilter – The current viur.core.db.Query instance the filters should be applied to

  • rawFilter – The dictionary of filters the client wants to have applied

Returns:

The modified viur.core.db.Query, None if the query is unsatisfiable.

_hashValueForUniquePropertyIndex(value: str | int) List[str]
getUniquePropertyIndexValues(skel: viur.core.skeleton.SkeletonInstance, name: str) List[str]

Returns a list of hashes for our current value(s), used to store in the uniquePropertyValue index.

getReferencedBlobs(skel: viur.core.skeleton.SkeletonInstance, name: str) Set[str]

Returns a set of blob keys referenced from this bone

performMagic(valuesCache: Dict, name: str, isAdd: bool)

This function applies “magically” functionality which f.e. inserts the current Date or the current user. :param isAdd: Signals whereever this is an add or edit operation.

postSavedHandler(skel: viur.core.skeleton.SkeletonInstance, boneName: str, key: str)

Can be overridden to perform further actions after the main entity has been written.

Parameters:
  • boneName – Name of this bone

  • skel – The skeleton this bone belongs to

  • key – The (new?) Database Key we’ve written to

postDeletedHandler(skel: viur.core.skeleton.SkeletonInstance, boneName: str, key: str)

Can be overridden to perform further actions after the main entity has been deleted.

Parameters:
  • skel – The skeleton this bone belongs to

  • boneName – Name of this bone

  • key – The old Database Key of the entity we’ve deleted

refresh(skel: viur.core.skeleton.SkeletonInstance, boneName: str) None

Refresh all values we might have cached from other entities.

mergeFrom(valuesCache: Dict, boneName: str, otherSkel: viur.core.skeleton.SkeletonInstance)

Clones the values from other into this instance

setBoneValue(skel: SkeletonInstance, boneName: str, value: Any, append: bool, language: None | str = None) bool

Set our value to ‘value’. Santy-Checks are performed; if the value is invalid, no modification will happen.

Parameters:
  • skel – Dictionary with the current values from the skeleton we belong to

  • boneName – The Bone which should be modified

  • value – The value that should be assigned. It’s type depends on the type of that bone

  • append – If true, the given value is appended to the values of that bone instead of replacing it. Only supported on bones with multiple=True

  • language – Set/append which language

Returns:

Wherever that operation succeeded or not.

getSearchTags(skel: viur.core.skeleton.SkeletonInstance, name: str) Set[str]

Returns a set of strings as search index for this bone.

Parameters:
  • skel – The skeleton instance where the values should be loaded from.

  • name – The name of the bone.

Returns:

A list of strings, extracted from the bone value

iter_bone_value(skel: viur.core.skeleton.SkeletonInstance, name: str) Iterator[Tuple[int | None, str | None, Any]]

Yield all values from the Skeleton related to this bone instance.

This method handles the multiple/languages cases, which could save a lot of if/elifs. It yields always a triplet: index, language, value Where index is the index (int) of a value inside a multiple bone, language the language (str) of a multi-language-bone and value the value inside this container. index or language is None if the bone is single or not multi-lang.

Parameters:
  • skel – The skeleton instance where the values should be loaded from.

  • name – The name of the bone.

Returns:

A generator which yields triplets.

class core.bones.ReadFromClientError
severity :ReadFromClientErrorSeverity
errorMessage :str
fieldPath :List[str]
invalidatedFields :List[str]
class core.bones.ReadFromClientErrorSeverity

Bases: enum.Enum

Generic enumeration.

Derive from this class to define new enumerations.

NotSet = 0
InvalidatesOther = 1
Empty = 2
Invalid = 3
class core.bones.UniqueValue
method :UniqueLockMethod
lockEmpty :bool
message :str
class core.bones.UniqueLockMethod

Bases: enum.Enum

Generic enumeration.

Derive from this class to define new enumerations.

SameValue = 1
SameSet = 2
SameList = 3
class core.bones.MultipleConstraints
minAmount :int = 0
maxAmount :int = 0
preventDuplicates :bool = False
class core.bones.BooleanBone(*, defaultValue: bool = False, **kwargs)

Bases: viur.core.bones.base.BaseBone

type = bool
singleValueFromClient(value, skel: viur.core.skeleton.SkeletonInstance, name: str, origData)
getEmptyValue()
isEmpty(rawValue: Any)
refresh(skel: viur.core.skeleton.SkeletonInstance, boneName: str) None

Inverse of serialize. Evaluates whats read from the datastore and populates this bone accordingly.

Parameters:

name – The property-name this bone has in its Skeleton (not the description!)

buildDBFilter(name: str, skel: viur.core.skeleton.SkeletonInstance, dbFilter: viur.core.db.Query, rawFilter: Dict, prefix: str | None = None) viur.core.db.Query
class core.bones.CaptchaBone(*, publicKey=None, privateKey=None, **kwargs)

Bases: viur.core.bones.base.BaseBone

type = captcha
serialize(skel: SkeletonInstance, name: str, parentIndexed: bool) bool
unserialize(skel, name) bool
fromClient(skel: SkeletonInstance, name: str, data: dict) None | List[viur.core.bones.base.ReadFromClientError]

Reads a value from the client. If this value is valid for this bone, store this value and return None. Otherwise our previous value is left unchanged and an error-message is returned.

Parameters:
  • name – Our name in the skeleton

  • dataUser-supplied request-data

Returns:

None or a list of errors

class core.bones.ColorBone(*, mode='rgb', **kwargs)

Bases: viur.core.bones.base.BaseBone

type = color
singleValueFromClient(value, skel: viur.core.skeleton.SkeletonInstance, name: str, origData)
class core.bones.CredentialBone(**kwargs)

Bases: viur.core.bones.string.StringBone

A bone for storing credentials. This is always empty if read from the database. If its saved, its ignored if its values is still empty. If its value is not empty, it will update the value in the database

type = str.credential
serialize(skel: SkeletonInstance, name: str, parentIndexed: bool) bool

Update the value only if a new value is supplied.

unserialize(valuesCache, name)

We’ll never read our value from the database.

singleValueFromClient(value, skel, name, origData)
class core.bones.DateBone(*, creationMagic: bool = False, date: bool = True, localize: bool = False, time: bool = True, updateMagic: bool = False, **kwargs)

Bases: viur.core.bones.base.BaseBone

type = date
singleValueFromClient(value: str, skel: viur.core.skeleton.SkeletonInstance, name: str, origData)

Reads a value from the client. If this value is valid for this bone, store this value and return None. Otherwise our previous value is left unchanged and an error-message is returned.

Value is assumed to be in local time zone only if both self.date and self.time are set to True and self.localize is True.

Value is valid if, when converted into String, it complies following formats:

  • is digit (may include one ‘-’) and valid POSIX timestamp: converted from timestamp; assumes UTC timezone

  • is digit (may include one ‘-’) and NOT valid POSIX timestamp and not date and time: interpreted as seconds after epoch

  • ‘now’: current time

  • ‘nowX’, where X converted into String is added as seconds to current time

  • ‘%H:%M:%S’ if not date and time

  • ‘%M:%S’ if not date and time

  • ‘%S’ if not date and time

  • ‘%Y-%m-%d %H:%M:%S’ (ISO date format)

  • ‘%Y-%m-%d %H:%M’ (ISO date format)

  • ‘%Y-%m-%d’ (ISO date format)

  • ‘%m/%d/%Y %H:%M:%S’ (US date-format)

  • ‘%m/%d/%Y %H:%M’ (US date-format)

  • ‘%m/%d/%Y’ (US date-format)

  • ‘%d.%m.%Y %H:%M:%S’ (EU date-format)

  • ‘%d.%m.%Y %H:%M’ (EU date-format)

  • ‘%d.%m.%Y’ (EU date-format)

The resulting year must be >= 1900.

Parameters:
  • name – Our name in the skeleton

  • valueUser-supplied request-data, has to be of valid format

Returns:

tuple[datetime or None, [Errors] or None]

isInvalid(value)

Ensure that year is >= 1900 Otherwise strftime will break later on.

guessTimeZone()

Guess the timezone the user is supposed to be in. If it cant be guessed, a safe default (UTC) is used

singleValueSerialize(value, skel: SkeletonInstance, name: str, parentIndexed: bool)
singleValueUnserialize(value)
buildDBFilter(name: str, skel: viur.core.skeleton.SkeletonInstance, dbFilter: viur.core.db.Query, rawFilter: Dict, prefix: str | None = None) viur.core.db.Query
performMagic(valuesCache, name, isAdd)
class core.bones.EmailBone

Bases: viur.core.bones.string.StringBone

type = str.email
isInvalid(value)
class core.bones.FileBone(*, derive: None | Dict[str, Any] = None, maxFileSize: None | int = None, validMimeTypes: None | List[str] = None, **kwargs)

Bases: viur.core.bones.treeleaf.TreeLeafBone

kind = file
type = relational.tree.leaf.file
refKeys = ['name', 'key', 'mimetype', 'dlkey', 'size', 'width', 'height', 'derived']
isInvalid(value)
postSavedHandler(skel, boneName, key)
getReferencedBlobs(skel: viur.core.skeleton.SkeletonInstance, name: str) Set[str]
refresh(skel, boneName)
class core.bones.KeyBone(*, descr: str = 'Key', readOnly: bool = True, visible: bool = False, allowed_kinds: None | List[str] = None, check: bool = False, **kwargs)

Bases: viur.core.bones.base.BaseBone

type = key
singleValueFromClient(value, skel, name, origData)
unserialize(skel: viur.core.skeleton.SkeletonValues, name: str) bool

Inverse of serialize. Evaluates whats read from the datastore and populates this bone accordingly. :param name: The property-name this bone has in its Skeleton (not the description!)

serialize(skel: SkeletonInstance, name: str, parentIndexed: bool) bool

Serializes this bone into something we can write into the datastore.

Parameters:

name – The property-name this bone has in its Skeleton (not the description!)

buildDBFilter(name: str, skel: viur.core.skeleton.SkeletonInstance, dbFilter: viur.core.db.Query, rawFilter: Dict, prefix: str | None = None) viur.core.db.Query

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)

Parameters:
  • name – The property-name this bone has in its Skeleton (not the description!)

  • skel – The viur.core.db.Query this bone is part of

  • dbFilter – The current viur.core.db.Query instance the filters should be applied to

  • rawFilter – The dictionary of filters the client wants to have applied

Returns:

The modified viur.core.db.Query

class core.bones.NumericBone(*, max: int | float = MAX, min: int | float = MIN, mode=None, precision: int = 0, **kwargs)

Bases: viur.core.bones.base.BaseBone

Holds numeric values. Can be used for ints and floats. For floats, the precision can be specified in decimal-places.

type = numeric
__setattr__(key, value)
isInvalid(value)
getEmptyValue()
isEmpty(rawValue: Any)
singleValueFromClient(value, skel, name, origData)
buildDBFilter(name: str, skel: viur.core.skeleton.SkeletonInstance, dbFilter: viur.core.db.Query, rawFilter: Dict, prefix: str | None = None) viur.core.db.Query
getSearchTags(skel: viur.core.skeleton.SkeletonInstance, name: str) Set[str]
class core.bones.PasswordBone

Bases: viur.core.bones.string.StringBone

A bone holding passwords. This is always empty if read from the database. If its saved, its ignored if its values is still empty. If its value is not empty, its hashed (with salt) and only the resulting hash will be written to the database

type = password
saltLength = 13
minPasswordLength = 8
passwordTests
passwordTestThreshold = 3
tooShortMessage
tooWeakMessage
isInvalid(value)
fromClient(skel: SkeletonInstance, name: str, data: dict) None | List[viur.core.bones.base.ReadFromClientError]
serialize(skel: SkeletonInstance, name: str, parentIndexed: bool) bool
unserialize(skeletonValues, name)
class core.bones.RandomSliceBone(*, visible=False, readOnly=True, slices=2, sliceSize=0.5, **kwargs)

Bases: viur.core.bones.base.BaseBone

Simulates the orderby=random from SQL. If you sort by this bone, the query will return a random set of elements from that query.

type = randomslice
serialize(skel: SkeletonInstance, name: str, parentIndexed: bool) bool

Serializes this bone into something we can write into the datastore.

This time, we just ignore whatever is set on this bone and write a randomly chosen float [0..1) as value for this bone.

Parameters:

name – The property-name this bone has in its Skeleton (not the description!)

buildDBSort(name: str, skel: viur.core.skeleton.SkeletonInstance, dbFilter: viur.core.db.Query, rawFilter: Dict) viur.core.db.Query | None

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!

This function is somewhat special as it doesn’t just change in which order the selected Elements are being returned - but also changes which Elements are beeing returned (=> a random selection)

Parameters:
  • name – The property-name this bone has in its Skeleton (not the description!)

  • skel – The viur.core.skeleton.Skeleton instance this bone is part of

  • dbFilter – The current viur.core.db.Query instance the filters should be applied to

  • rawFilter – The dictionary of filters the client wants to have applied

Returns:

The modified viur.core.db.Query

calculateInternalMultiQueryLimit(query: viur.core.db.Query, targetAmount: int) int

Tells viur.core.db.Query How much entries should be fetched in each subquery.

Parameters:

targetAmount – How many entries shall be returned from db.Query

Returns:

The amount of elements db.Query should fetch on each subquery

customMultiQueryMerge(dbFilter: viur.core.db.Query, result: List[viur.core.db.Entity], targetAmount: int) List[viur.core.db.Entity]

Randomly returns ‘targetAmount’ elements from ‘result’

Parameters:
  • dbFilter – The db.Query calling this function

  • result – The list of results for each subquery we’ve run

  • targetAmount – How many results should be returned from db.Query

Returns:

list of elements which should be returned from db.Query

class core.bones.RawBone

Bases: viur.core.bones.base.BaseBone

Stores it’s data without applying any pre/post-processing or filtering. Can be used to store non-html content. Use the dot-notation like “raw.markdown” or similar to describe subsequent types.

..Warning: Using this bone will lead to security vulnerabilities like reflected XSS unless the data is either

otherwise validated/stripped or from a trusted source! Don’t use this unless you fully understand it’s implications!

type = raw
singleValueFromClient(value, skel, name, origData)
class core.bones.RecordBone(*, format: str = None, indexed: bool = False, using: viur.core.skeleton.RelSkel = None, **kwargs)

Bases: viur.core.bones.base.BaseBone

type = record
singleValueUnserialize(val)
singleValueSerialize(value, skel: SkeletonInstance, name: str, parentIndexed: bool)
parseSubfieldsFromClient() bool

Whenever this request should try to parse subfields submitted from the client. Set only to true if you expect a list of dicts to be transmitted

singleValueFromClient(value, skel, name, origData)
getSearchTags(skel: viur.core.skeleton.SkeletonInstance, name: str) Set[str]
getSearchDocumentFields(valuesCache, name, prefix='')
getReferencedBlobs(skel: viur.core.skeleton.SkeletonInstance, name: str) Set[str]
abstract getUniquePropertyIndexValues(valuesCache: dict, name: str) List[str]

This is intentionally not defined as we don’t now how to derive a key from the relskel being using (ie. which Fields to include and how).

class core.bones.RelationalBone(*, consistency: RelationalConsistency = RelationalConsistency.Ignore, format: str = '$(dest.name)', kind: str = None, module: str | None = None, parentKeys: List[str] | None = None, refKeys: List[str] | None = None, updateLevel: RelationalUpdateLevel = RelationalUpdateLevel.Always, using: viur.core.skeleton.RelSkel | None = None, **kwargs)

Bases: viur.core.bones.base.BaseBone

This is our magic class implementing relations.

This implementation is read-efficient, e.g. filtering by relational-properties only costs an additional small-op for each entity returned. However, it costs several more write-ops for writing an entity to the db. (These costs are somewhat around additional (4+len(refKeys)+len(parentKeys)) write-ops for each referenced property) for multiple=True RelationalBones and (4+len(refKeys)) for n:1 relations)

So don’t use this if you expect data being read less frequently than written! (Sorry, we don’t have a write-efficient method yet) To speedup writes to (maybe) referenced entities, information in these relations isn’t updated instantly. Once a skeleton is updated, a deferred task is kicked off which updates the references to that skeleton (if any). As a result, you might see stale data until this task has been finished.

Example:

  • Entity A references Entity B.

  • Both have a property “name”.

  • Entity B gets updated (it name changes).

  • As “A” has a copy of entity “B”s values, you’ll see “B”s old name inside the values of the RelationalBone when fetching entity A.

If you filter a list by relational properties, this will also use the old data! (Eg. filtering A’s list by B’s new name won’t return any result)

refKeys = ['key', 'name']
parentKeys = ['key', 'name']
type = relational
kind
setSystemInitialized()
_getSkels()
singleValueUnserialize(val)

Restores one of our values (including the Rel- and Using-Skel) from the serialized data read from the datastore :param value: Json-Encoded datastore property :return: Our Value (with restored RelSkel and using-Skel)

serialize(skel: SkeletonInstance, name: str, parentIndexed: bool) bool
delete(skel: viur.core.skeleton.SkeletonInstance, name: str)

Ensure any outgoing relational lock is cleared

Parameters:
  • skel

  • name

Returns:

postSavedHandler(skel, boneName, key)
postDeletedHandler(skel, boneName, key)
isInvalid(key)
parseSubfieldsFromClient()
singleValueFromClient(value, skel, name, origData)
_rewriteQuery(name, skel, dbFilter, rawFilter)

Rewrites a datastore query to operate on “viur-relations” instead of the original kind. This is needed to perform relational queries on n:m relations.

buildDBFilter(name: str, skel: viur.core.skeleton.SkeletonInstance, dbFilter: viur.core.db.Query, rawFilter: Dict, prefix: str | None = None) viur.core.db.Query
buildDBSort(name: str, skel: viur.core.skeleton.SkeletonInstance, dbFilter: viur.core.db.Query, rawFilter: Dict) viur.core.db.Query | None
filterHook(name, query, param, value)

Hook installed by buildDbFilter. This rewrites all filters added to the query after buildDbFilter has been run to match the layout of our viur-relations index. Also performs sanity checks wherever this query is possible at all.

orderHook(name, query, orderings)

Hook installed by buildDbFilter. This rewrites all orderings added to the query after buildDbFilter has been run to match the layout of our viur-relations index. Also performs sanity checks wherever this query is possible at all.

refresh(skel, boneName)

Refresh all values we might have cached from other entities.

getSearchTags(skel: viur.core.skeleton.SkeletonInstance, name: str) Set[str]
createRelSkelFromKey(key: str | viur.core.db.Key, rel: dict | None = None)

Creates a relSkel instance valid for this bone from the given database key.

setBoneValue(skel: SkeletonInstance, boneName: str, value: Any, append: bool, language: None | str = None) bool

Set our value to ‘value’. Santy-Checks are performed; if the value is invalid, no modification will happen.

Parameters:
  • skel – Dictionary with the current values from the skeleton we belong to

  • boneName – The Bone which should be modified

  • value – The value that should be assigned. It’s type depends on the type of that bone

  • append – If true, the given value is appended to the values of that bone instead of replacing it. Only supported on bones with multiple=True

  • language – Set/append which language

Returns:

Wherever that operation succeeded or not.

getReferencedBlobs(skel: viur.core.skeleton.SkeletonInstance, name: str) Set[str]
getUniquePropertyIndexValues(valuesCache: dict, name: str) List[str]

By default, RelationalBones distinct by referenced keys. Should be overridden if a different behaviour is required (eg. examine values from prop:usingSkel)

class core.bones.RelationalConsistency

Bases: enum.Enum

Generic enumeration.

Derive from this class to define new enumerations.

Ignore = 1
PreventDeletion = 2
SetNull = 3
CascadeDeletion = 4
class core.bones.SelectCountryBone(*, codes=ISO2, values=None, **kwargs)

Bases: viur.core.bones.select.SelectBone

type = select.country
ISO2 = 2
ISO3 = 3
singleValueUnserialize(val)
class core.bones.SelectBone(*, defaultValue: None | Dict[str, SelectBoneMultiple | SelectBoneValue] | SelectBoneMultiple = None, values: Dict | List | Tuple | Callable = (), **kwargs)

Bases: viur.core.bones.base.BaseBone

type = select
__getattribute__(item)
singleValueFromClient(value, skel, name, origData)
class core.bones.SortIndexBone(*, defaultValue: int | float = lambda *args, **kwargs: ..., descr: str = 'SortIndex', precision: int = 8, **kwargs)

Bases: viur.core.bones.numeric.NumericBone

type = numeric.sortindex
class core.bones.SpatialBone(*, boundsLat: Tuple[float, float], boundsLng: Tuple[float, float], gridDimensions: Tuple[int, int], **kwargs)

Bases: viur.core.bones.base.BaseBone

Allows to query by Elements close to a given position. Prior to use, you must specify for which region of the map the index should be build. This region should be as small as possible for best accuracy. You cannot use the whole world, as no boundary wraps are been performed. GridDimensions specifies into how many sub-regions the map will be split. Results further away than the size of these sub-regions won’t be considered within a search by this algorithm.

Example:

If you use this bone to query your data for the nearest pubs, you might want to this algorithm to consider results up to 100km distance, but not results that are 500km away. Setting the size of these sub-regions to roughly 100km width/height allows this algorithm to exclude results further than 200km away on database-query-level, therefore drastically improving performance and reducing costs per query.

Example region: Germany: boundsLat=(46.988, 55.022), boundsLng=(4.997, 15.148)

type = spatial
getGridSize()
Returns:

the size of our sub-regions in (fractions-of-latitude, fractions-of-longitude)

Return type:

(float, float)

isInvalid(value: Tuple[float, float]) str | bool

Tests, if the point given by ‘value’ is inside our boundaries. We’ll reject all values outside that region. :param value: (latitude, longitude) of the location of this entry. :return: An error-description or False if the value is valid :rtype: str | False

singleValueSerialize(value, skel: SkeletonInstance, name: str, parentIndexed: bool)
singleValueUnserialize(val)
parseSubfieldsFromClient()
isEmpty(rawValue: Any)
getEmptyValue() Tuple[float, float]

If you need a special marker for empty, use 91.0, 181.0. These are both out of range for Latitude (-90, +90) and Longitude (-180, 180) but will be accepted by Vi and Admin

singleValueFromClient(value: Dict, skel: str, name: str, origData: Dict)

Reads a value from the client. If this value is valid for this bone, store this value and return None. Otherwise our previous value is left unchanged and an error-message is returned.

Parameters:
  • name – Our name in the skeleton

  • valueUser-supplied request-data

buildDBFilter(name: str, skel: viur.core.skeleton.SkeletonInstance, dbFilter: viur.core.db.Query, rawFilter: Dict, prefix: str | None = None) viur.core.db.Query

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)

For detailed information, how this geo-spatial search works, see the ViUR documentation.

Parameters:
  • name – The property-name this bone has in its Skeleton (not the description!)

  • skel – The viur.core.db.Query this bone is part of

  • dbFilter – The current viur.core.db.Query instance the filters should be applied to

  • rawFilter – The dictionary of filters the client wants to have applied

Returns:

The modified viur.core.db.Query

calculateInternalMultiQueryLimit(dbQuery: viur.core.db.Query, targetAmount: int)

Tells viur.core.db.Query How much entries should be fetched in each subquery.

Parameters:

targetAmount – How many entries shall be returned from db.Query

Returns:

The amount of elements db.Query should fetch on each subquery

customMultiQueryMerge(name, lat, lng, dbFilter: viur.core.db.Query, result: List[viur.core.db.Entity], targetAmount: int) List[viur.core.db.Entity]

Randomly returns ‘targetAmount’ elements from ‘result’

Parameters:
  • name

  • lat

  • lng

  • dbFilter – The db.Query calling this function

  • result – The list of results for each subquery we’ve run

  • targetAmount – How many results should be returned from db.Query

Returns:

List of elements which should be returned from db.Query

setBoneValue(skel: SkeletonInstance, boneName: str, value: Any, append: bool, language: None | str = None) bool

Set our value to ‘value’. Santy-Checks are performed; if the value is invalid, we flip our value back to its original (default) value and return false.

Parameters:
  • skel – Dictionary with the current values from the skeleton we belong to

  • boneName – The Bone which should be modified

  • value – The value that should be assigned. It’s type depends on the type of that bone

  • append – If true, the given value is appended to the values of that bone instead of replacing it. Only supported on bones with multiple=True

Returns:

Wherever that operation succeeded or not.

class core.bones.StringBone(*, caseSensitive: bool = True, maxLength: int = 254, **kwargs)

Bases: viur.core.bones.base.BaseBone

type = str
singleValueSerialize(value, skel: SkeletonInstance, name: str, parentIndexed: bool)
singleValueUnserialize(value)
getEmptyValue()
isEmpty(value)
singleValueFromClient(value, skel, name, origData)
buildDBFilter(name: str, skel: viur.core.skeleton.SkeletonInstance, dbFilter: viur.core.db.Query, rawFilter: Dict, prefix: str | None = None) viur.core.db.Query
buildDBSort(name: str, skel: viur.core.skeleton.SkeletonInstance, dbFilter: viur.core.db.Query, rawFilter: Dict) viur.core.db.Query | None
getSearchTags(skel: viur.core.skeleton.SkeletonInstance, name: str) Set[str]
getUniquePropertyIndexValues(skel, name: str) List[str]
class core.bones.TextBone(*, validHtml: None | Dict = __undefinedC__, maxLength: int = 200000, srcSet: Dict[str, List] | None = None, indexed: bool = False, **kwargs)

Bases: viur.core.bones.base.BaseBone

class __undefinedC__
type = text
singleValueSerialize(value, skel: SkeletonInstance, name: str, parentIndexed: bool)
singleValueFromClient(value, skel, name, origData)
getEmptyValue()
isInvalid(value)

Returns None if the value would be valid for this bone, an error-message otherwise.

getReferencedBlobs(skel: viur.core.skeleton.SkeletonInstance, name: str) Set[str]

Parse our html for embedded img or hrefs pointing to files. These will be locked, so even if they are deleted from the file browser, we’ll still keep that blob alive so we don’t have broken links/images in this bone.

refresh(skel, boneName) None

Re-parse our text. This will cause our src-set to rebuild.

getSearchTags(skel: viur.core.skeleton.SkeletonInstance, name: str) Set[str]
getUniquePropertyIndexValues(valuesCache: dict, name: str) List[str]
class core.bones.TreeLeafBone(**kwargs)

Bases: viur.core.bones.relational.RelationalBone

type = relational.tree.leaf
class core.bones.TreeNodeBone

Bases: viur.core.bones.relational.RelationalBone

type = relational.tree.node
class core.bones.UserBone(*, creationMagic=False, updateMagic=False, visible=None, readOnly=False, **kwargs)

Bases: viur.core.bones.relational.RelationalBone

kind = user
datafields = ['name']
performMagic(skel, key, isAdd, *args, **kwargs)