Skip to content

Commit

Permalink
added python 3 and uuid entity id support
Browse files Browse the repository at this point in the history
  • Loading branch information
musamusa committed May 4, 2018
1 parent 41e99fa commit a2f21c4
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 13 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@
_build
build
django_eav.egg-info/*
*.DS_Store
env/
.idea/
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ django-eav
Introduction
------------


django-eav provides an Entity-Attribute-Value storage model for django apps.

For a decent explanation of what an Entity-Attribute-Value storage model is,
Expand Down
5 changes: 4 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ For example::

eav.register(MyModel, MyEavConfigClass)

To override ``entity_id`` to use ``entity_uuid`` for entity relationship with
model add ``EAV_ENTITY_ID_TYPE='uuid'`` to use ``entity_uuid`` (defaults to
int for ``entity_id``)

Using Attributes
================
Expand All @@ -151,7 +154,7 @@ First, let's create some attributes::

>>> Attribute.objects.create(name='Weight', datatype=Attribute.TYPE_FLOAT)
>>> Attribute.objects.create(name='Height', datatype=Attribute.TYPE_INT)
>>> Attribute.objects.create(name='Is pregant?', datatype=Attribute.TYPE_BOOLEAN)
>>> Attribute.objects.create(name='Is pregnant?', datatype=Attribute.TYPE_BOOLEAN)

Now let's create a patient, and set some of these attributes::

Expand Down
2 changes: 2 additions & 0 deletions eav/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

from .models import Attribute, Value, EnumValue, EnumGroup


class BaseEntityAdmin(ModelAdmin):

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
Expand Down Expand Up @@ -93,6 +94,7 @@ def get_fieldsets(self, request, obj=None):

return [(None, {'fields': list(form.fields.keys())})]


class AttributeAdmin(ModelAdmin):
list_display = ('name', 'content_type', 'slug', 'datatype', 'description', 'site')
list_filter = ['site']
Expand Down
51 changes: 51 additions & 0 deletions eav/migrations/0003_auto_20161104_0922.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.3 on 2016-11-04 09:22
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion
import eav.fields


class Migration(migrations.Migration):

dependencies = [
('eav', '0002_auto_20161014_0157'),
]

operations = [
migrations.CreateModel(
name='Encounter',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('num', models.PositiveSmallIntegerField()),
],
),
migrations.CreateModel(
name='Patient',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=12)),
],
),
migrations.AlterField(
model_name='attribute',
name='datatype',
field=eav.fields.EavDatatypeField(choices=[('text', 'Text'), ('float', 'Float'), ('int', 'Integer'), ('date', 'Date'), ('bool', 'True / False'), ('object', 'Django Object'), ('enum', 'Multiple Choice')], max_length=6, verbose_name='data type'),
),
migrations.AddField(
model_name='encounter',
name='patient',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='eav.Patient'),
),
migrations.AddField(
model_name='value',
name='entity_uuid',
field=models.UUIDField(blank=True, null=True),
),
migrations.AlterField(
model_name='value',
name='entity_id',
field=models.IntegerField(blank=True, null=True),
),
]
26 changes: 15 additions & 11 deletions eav/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@

from .validators import *
from .fields import EavSlugField, EavDatatypeField
from .utils.utilities import Utils


class EnumValue(models.Model):
Expand Down Expand Up @@ -86,7 +87,7 @@ class EnumValue(models.Model):
@python_2_unicode_compatible
def __str__(self):
return self.value


class EnumGroup(models.Model):
'''
Expand Down Expand Up @@ -304,16 +305,15 @@ def save_value(self, entity, value):
Attribute and *entity*, it will delete that :class:`Value` object.
'''
ct = ContentType.objects.get_for_model(entity)
entity_dict = dict(entity_ct=ct,
attribute=self)
entity_dict[Value.entity_id_type] = entity.pk
try:
value_obj = self.value_set.get(entity_ct=ct,
entity_id=entity.pk,
attribute=self)
value_obj = self.value_set.get(**entity_dict)
except Value.DoesNotExist:
if value == None or value == '':
return
value_obj = Value.objects.create(entity_ct=ct,
entity_id=entity.pk,
attribute=self)
value_obj = Value.objects.create(**entity_dict)
if value == None or value == '':
value_obj.delete()
return
Expand Down Expand Up @@ -347,10 +347,13 @@ class Value(models.Model):
<Value: crazy_dev_user - Favorite Drink: "red bull">
'''

entity_id_type = Utils().get_eav_entity_id_type()

entity_ct = models.ForeignKey(ContentType, related_name='value_entities')
entity_id = models.IntegerField()
entity_id = models.IntegerField(blank=True, null=True)
entity_uuid = models.UUIDField(blank=True, null=True)
entity = generic.GenericForeignKey(ct_field='entity_ct',
fk_field='entity_id')
fk_field=entity_id_type)

value_text = models.TextField(blank=True, null=True)
value_float = models.FloatField(blank=True, null=True)
Expand Down Expand Up @@ -521,8 +524,9 @@ def get_values(self):
'''
Get all set :class:`Value` objects for self.model
'''
return Value.objects.filter(entity_ct=self.ct,
entity_id=self.model.pk).select_related()
entiity_filter = dict(entity_ct=self.ct)
entiity_filter[Value.entity_id_type] = self.model.pk
return Value.objects.filter(**entiity_filter).select_related()

def get_all_attribute_slugs(self):
'''
Expand Down
2 changes: 1 addition & 1 deletion eav/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def _attach_generic_relation(self):
gr_name = self.config_cls.generic_relation_attr.lower()
generic_relation = \
generic.GenericRelation(Value,
object_id_field='entity_id',
object_id_field=Value.entity_id_type,
content_type_field='entity_ct',
related_query_name=rel_name)
generic_relation.contribute_to_class(self.model_cls, gr_name)
Expand Down
Empty file added eav/utils/__init__.py
Empty file.
16 changes: 16 additions & 0 deletions eav/utils/utilities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from django.conf import settings


class Utils(object):
ENTITY_ID_TYPES = {
'uuid': 'entity_uuid',
'int': 'entity_id'
}

def get_eav_entity_id_type(self):
key = getattr(settings, 'EAV_ENTITY_ID_TYPE', 'int')
try:
return self.ENTITY_ID_TYPES[key]
except KeyError:
print('%s not supported, kindly try uuid or int, defaulting to int' % key)
return self.ENTITY_ID_TYPES['int']
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Django==1.10.3
eav-django==1.4.7

0 comments on commit a2f21c4

Please sign in to comment.