This module defines the four concrete, non-abstract models:
Along with the Entity helper class.
Putting the A in EAV. This holds the attributes, or concepts. Examples of possible Attributes: color, height, weight, number of children, number of patients, has fever?, etc...
Each attribute has a name, and a description, along with a slug that must be unique. If you don’t provide a slug, a default slug (derrived from name), will be created.
The required field is a boolean that indicates whether this EAV attribute is required for entitys to which it applies. It defaults to False.
Warning
Just like a normal model field that is required, you will not be able to save or create any entity object for which this attribute applies, without first setting this EAV attribute.
There are 7 possible values for datatype:
- int (TYPE_INT)
- float (TYPE_FLOAT)
- text (TYPE_TEXT)
- date (TYPE_DATE)
- bool (TYPE_BOOLEAN)
- object (TYPE_OBJECT)
- enum (TYPE_ENUM)
Examples:
>>> Attribute.objects.create(name='Height', datatype=Attribute.TYPE_INT)
<Attribute: Height (Float)>
>>> Attribute.objects.create(name='Color', datatype=Attribute.TYPE_TEXT)
<Attribute: Color (Text)>
>>> yes = EnumValue.objects.create(value='yes')
>>> no = EnumValue.objects.create(value='no')
>>> unkown = EnumValue.objects.create(value='unkown')
>>> ynu = EnumGroup.objects.create(name='Yes / No / Unkown')
>>> ynu.enums.add(yes, no, unkown)
>>> Atrribute.objects.create(name='Has Fever?',
... datatype=Attribute.TYPE_ENUM,
... enum_group=ynu)
<Attribute: Has Fever? (Multiple Choice)>
Warning
Once an Attribute has been used by an entity, you can not change it’s datatype.
Returns the appropriate validator function from validators as a list (of length one) for the datatype.
Note
The reason it returns it as a list, is eventually we may want this method to look elsewhere for additional attribute specific validators to return as well as the default, built-in one.
Called with entity, any django object registered with eav, and value, the Value this attribute for entity should be set to.
If a Value object for this entity and attribute doesn’t exist, one will be created.
The helper class that will be attached to any entity registered with eav.
EnumGroup objects have two fields- a name CharField and enums, a ManyToManyField to EnumValue. Attribute classes with datatype TYPE_ENUM have a ForeignKey field to EnumGroup.
See EnumValue for an example.
EnumValue objects are the value ‘choices’ to multiple choice TYPE_ENUM Attribute objects.
They have only one field, value, a``CharField`` that must be unique.
For example:
>>> yes = EnumValue.objects.create(value='yes')
>>> no = EnumValue.objects.create(value='no')
>>> unkown = EnumValue.objects.create(value='unkown')
>>> ynu = EnumGroup.objects.create(name='Yes / No / Unkown')
>>> ynu.enums.add(yes, no, unkown)
>>> Atrribute.objects.create(name='Has Fever?',
... datatype=Attribute.TYPE_ENUM,
... enum_group=ynu)
Note
The same EnumValue objects should be reused within multiple EnumGroups. For example, if you have one EnumGroup called: Yes / No / Unkown and another called Yes / No / Not applicable, you should only have a total of four EnumValues objects, as you should have used the same Yes and No EnumValues for both EnumGroups.
Putting the V in EAV. This model stores the value for one particular Attribute for some entity.
As with most EAV implementations, most of the columns of this model will be blank, as onle one value_ field will be used.
Example:
>>> import eav
>>> from django.contrib.auth.models import User
>>> eav.register(User)
>>> u = User.objects.create(username='crazy_dev_user')
>>> a = Attribute.objects.create(name='Favorite Drink', datatype='text',
... slug='fav_drink')
>>> Value.objects.create(entity=u, attribute=a, value_text='red bull')
<Value: crazy_dev_user - Favorite Drink: "red bull">
This module contains a validator for each Attribute datatype.
A validator is a callable that takes a value and raises a ValidationError if it doesn’t meet some criteria. (see django validators)
These validators are called by the validate_value() method in the Attribute model.
Contains two custom fields:
The slug field used by Attribute
The forms used for admin integration
ModelForm for entity with support for EAV attributes. Form fields are created on the fly depending on Schema defined for given entity instance. If no schema is defined (i.e. the entity instance has not been saved yet), only static fields are used. However, on form validation the schema will be retrieved and EAV fields dynamically added to the form, so when the validation is actually done, all EAV fields are present in it (unless Rubric is not defined).
Saves this form‘s cleaned_data into model instance self.instance and related EAV attributes.
Returns instance.
Contains the custom manager used by entities registered with eav.
Our custom manager, overriding models.Manager
Accepts a model class and a key, value. Recurisively replaces any eav filter with a subquery.
For example:
key = 'eav__height'
value = 5
Would return:
key = 'eav_values__in'
value = Values.objects.filter(value_int=5, attribute__slug='height')
This contains the registry classes
The default EevConfig class used if it is not overriden on registration. This is where all the default eav attribute names are defined.
Handles registration through the register() and unregister() methods.
Registers model_cls with eav. You can pass an optional config_cls to override the EavConfig defaults.
Note
Multiple registrations for the same entity are harmlessly ignored.
Unregisters model_cls with eav.
Note
Unregistering a class not already registered is harmlessly ignored.