diff --git a/.gitignore b/.gitignore index a4c7e1f..f529a5f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ *.pyc -greav -omrs ~* *.orig *.db diff --git a/eav_ng/__init__.py b/eav_ng/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/fields.py b/fields.py new file mode 100644 index 0000000..058879a --- /dev/null +++ b/fields.py @@ -0,0 +1,66 @@ +import uuid + +from django.db import models +from django.utils.translation import ugettext_lazy as _ + + +class UuidField(models.CharField): + ''' + A field which stores a UUID value in hex format. This may also have + the Boolean attribute 'auto' which will set the value on initial save to a + new UUID value (calculated using the UUID1 method). Note that while all + UUIDs are expected to be unique we enforce this with a DB constraint. + ''' + __metaclass__ = models.SubfieldBase + + def __init__(self, version=4, node=None, clock_seq=None, namespace=None, auto=False, name=None, *args, **kwargs): + self.auto = auto + self.version = version + # Set this as a fixed value, we store UUIDs in text. + kwargs['max_length'] = 32 + if auto: + # Do not let the user edit UUIDs if they are auto-assigned. + kwargs['editable'] = False + kwargs['blank'] = True + kwargs['unique'] = True + if version == 1: + self.node, self.clock_seq = node, clock_seq + elif version in (3, 5): + self.namespace, self.name = namespace, name + super(UuidField, self).__init__(*args, **kwargs) + + def _create_uuid(self): + if self.version == 1: + args = (self.node, self.clock_seq) + elif self.version in (3, 5): + args = (self.namespace, self.name) + else: + args = () + return getattr(uuid, 'uuid%s' % (self.version,))(*args) + + def db_type(self): + return 'char' + + def pre_save(self, model_instance, add): + value = getattr(model_instance, self.attname, None) + if not value and self.auto: + # Assign a new value for this attribute if required. + value = self._create_uuid() + setattr(model_instance, self.attname, value) + return value + + def to_python(self, value): + if not value: return + if not isinstance(value, uuid.UUID): + value = uuid.UUID(value) + return value + + def get_db_prep_save(self, value): + if not value: return + assert(isinstance(value, uuid.UUID)) + return value.hex + + def get_db_prep_value(self, value): + if not value: return + assert(isinstance(value, uuid.UUID)) + return unicode(value) diff --git a/fixtures/auth.json b/fixtures/auth.json deleted file mode 100644 index 46e9b72..0000000 --- a/fixtures/auth.json +++ /dev/null @@ -1,20 +0,0 @@ -[ - { - "pk": 1, - "model": "auth.user", - "fields": { - "username": "dgelvin", - "first_name": "", - "last_name": "", - "is_active": true, - "is_superuser": true, - "is_staff": true, - "last_login": "2010-09-04 03:47:21", - "groups": [], - "user_permissions": [], - "password": "sha1$1b628$0cba7ecb1e1c6f532a24f17ada2b325e127c56e2", - "email": "a@a.com", - "date_joined": "2010-09-04 03:47:21" - } - } -] diff --git a/fixtures/fake.json b/fixtures/fake.json deleted file mode 100644 index 622d1a8..0000000 --- a/fixtures/fake.json +++ /dev/null @@ -1,101 +0,0 @@ -[ - { - "pk": 1, - "model": "greav.clinic", - "fields": { - "name": "Ruhiira HC III" - } - }, - { - "pk": 1, - "model": "greav.household", - "fields": { - "location": "Uganda" - } - }, - { - "pk": 1, - "model": "greav.patient", - "fields": { - "dob": null, - "gender": "F", - "first_name": "Jane", - "last_name": "Smith", - "household": 1 - } - }, - { - "pk": 2, - "model": "greav.patient", - "fields": { - "dob": null, - "gender": "M", - "first_name": "John", - "last_name": "Doe", - "household": 1 - } - }, - { - "pk": 1, - "model": "greav.householdencounter", - "fields": { - "household": 1 - } - }, - { - "pk": 2, - "model": "greav.patientencounter", - "fields": { - "patient": 2 - } - }, - { - "pk": 3, - "model": "greav.clinicreport", - "fields": { - "clinic": 1 - } - }, - { - "pk": 2, - "model": "greav.patientencounter", - "fields": { - "patient": 2 - } - }, - { - "pk": 1, - "model": "greav.householdencounter", - "fields": { - "household": 1 - } - }, - { - "pk": 3, - "model": "greav.clinicreport", - "fields": { - "clinic": 1 - } - }, - { - "pk": "f1a3c11e-14db-4d80-ae92-96f37ce40c3c", - "model": "greav.concept", - "fields": { - "name": "Weight (kg)" - } - }, - { - "pk": "93eba226-54a9-4702-846a-b8b26e9b0b0a", - "model": "greav.concept", - "fields": { - "name": "Has bednet" - } - }, - { - "pk": "46654489-254d-4552-91e1-50b638df1571", - "model": "greav.concept", - "fields": { - "name": "OPD Attendance" - } - } -] diff --git a/manage.py b/manage.py deleted file mode 100755 index 5e78ea9..0000000 --- a/manage.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python -from django.core.management import execute_manager -try: - import settings # Assumed to be in the same directory. -except ImportError: - import sys - sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) - sys.exit(1) - -if __name__ == "__main__": - execute_manager(settings) diff --git a/eav_ng/managers.py b/managers.py similarity index 100% rename from eav_ng/managers.py rename to managers.py diff --git a/eav_ng/models.py b/models.py similarity index 89% rename from eav_ng/models.py rename to models.py index 03e33ee..922e032 100644 --- a/eav_ng/models.py +++ b/models.py @@ -3,17 +3,19 @@ from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes import generic from django.utils.translation import ugettext_lazy as _ +from .fields import UuidField + class EavAttribute(models.Model): ''' The A model in E-A-V. This holds the 'concepts' along with the data type something like: - >>> EavAttribute.objects.create(name='height', datatype='float') - - or + >>> EavAttribute.objects.create(name='height', datatype='float') + >>> EavAttribute.objects.create(name='color', datatype='text') + ''' class Meta: ordering = ['name'] @@ -26,25 +28,27 @@ class EavAttribute(models.Model): #TYPE_MANY = 'many' DATATYPE_CHOICES = ( - (TYPE_TEXT, _("Text")), - (TYPE_FLOAT, _("Float")), - (TYPE_INT, _("Integer")), - (TYPE_DATE, _("Date")), - (TYPE_BOOLEAN, _("True / False")), + (TYPE_TEXT, _(u"Text")), + (TYPE_FLOAT, _(u"Float")), + (TYPE_INT, _(u"Integer")), + (TYPE_DATE, _(u"Date")), + (TYPE_BOOLEAN, _(u"True / False")), #(TYPE_MANY, _('multiple choices')), ) #TODO Force name to lowercase? Don't allow spaces in name name = models.CharField(_(u"name"), max_length=100, - help_text=_(u"user-friendly attribute name")) + help_text=_(u"User-friendly attribute name")) help_text = models.CharField(_(u"help text"), max_length=250, blank=True, null=True, - help_text=_(u"Short description for user")) + help_text=_(u"Short description")) datatype = models.CharField(_(u"data type"), max_length=6, choices=DATATYPE_CHOICES) + uuid = UuidField(auto=True) + def get_value_for_entity(self, entity): ''' Passed any object that may be used as an 'entity' object (is linked @@ -103,11 +107,11 @@ class EavValue(models.Model): self.value_text = self.value_float = self.value_int = self.value_date = None def _get_value(self): - return getattr(self, "value_%s" % self.attribute.datatype) + return getattr(self, 'value_%s' % self.attribute.datatype) def _set_value(self, new_value): self._blank() - setattr(self, "value_%s" % self.attribute.datatype, new_value) + setattr(self, 'value_%s' % self.attribute.datatype, new_value) value = property(_get_value, _set_value) @@ -127,8 +131,9 @@ class EavEntity(object): attribute = self.get_attribute_by_name(name) value = attribute.get_value_for_entity(self.model) return value.value if value else None - raise AttributeError('%s EAV does not have attribute named "%s".' % - (self.model._meta.object_name, name)) + raise AttributeError(_(u"%s EAV does not have attribute " \ + u"named \"%s\".") % \ + (self.model._meta.object_name, name)) def save(self): for attribute in self.get_all_attributes(): diff --git a/settings.py b/settings.py deleted file mode 100644 index 5079346..0000000 --- a/settings.py +++ /dev/null @@ -1,105 +0,0 @@ -# Django settings for myeav project. - -DEBUG = True -TEMPLATE_DEBUG = DEBUG - -ADMINS = ( - # ('Your Name', 'your_email@domain.com'), -) - -MANAGERS = ADMINS - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. - 'NAME': 'eav_ng.db', # Or path to database file if using sqlite3. - 'USER': '', # Not used with sqlite3. - 'PASSWORD': '', # Not used with sqlite3. - 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. - 'PORT': '', # Set to empty string for default. Not used with sqlite3. - } -} - -# Local time zone for this installation. Choices can be found here: -# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name -# although not all choices may be available on all operating systems. -# On Unix systems, a value of None will cause Django to use the same -# timezone as the operating system. -# If running in a Windows environment this must be set to the same as your -# system time zone. -TIME_ZONE = 'America/Chicago' - -# Language code for this installation. All choices can be found here: -# http://www.i18nguy.com/unicode/language-identifiers.html -LANGUAGE_CODE = 'en-us' - -SITE_ID = 1 - -# If you set this to False, Django will make some optimizations so as not -# to load the internationalization machinery. -USE_I18N = True - -# If you set this to False, Django will not format dates, numbers and -# calendars according to the current locale -USE_L10N = True - -# Absolute path to the directory that holds media. -# Example: "/home/media/media.lawrence.com/" -MEDIA_ROOT = '' - -# URL that handles the media served from MEDIA_ROOT. Make sure to use a -# trailing slash if there is a path component (optional in other cases). -# Examples: "http://media.lawrence.com", "http://example.com/media/" -MEDIA_URL = '' - -# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a -# trailing slash. -# Examples: "http://foo.com/media/", "/media/". -ADMIN_MEDIA_PREFIX = '/media/' - -# Make this unique, and don't share it with anybody. -SECRET_KEY = 's#h&3e_obkdm2ou$y76xn#1ll&9ld!q(na)axko4m0ky*2za3q' - -# List of callables that know how to import templates from various sources. -TEMPLATE_LOADERS = ( - 'django.template.loaders.filesystem.Loader', - 'django.template.loaders.app_directories.Loader', -# 'django.template.loaders.eggs.Loader', -) - -MIDDLEWARE_CLASSES = ( - 'devserver.middleware.DevServerMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', -) - -ROOT_URLCONF = 'myeav.urls' - -TEMPLATE_DIRS = ( - # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". - # Always use forward slashes, even on Windows. - # Don't forget to use absolute paths, not relative paths. -) - -DEVSERVER_MODULES = ( - 'devserver.modules.sql.SQLRealTimeModule', - 'devserver.modules.sql.SQLSummaryModule', - 'devserver.modules.profile.ProfileSummaryModule', -) - -INSTALLED_APPS = ( - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.sites', - 'django.contrib.messages', - 'django.contrib.admin', - 'django_extensions', - 'eav', - 'eav_ng', - 'omrs' -) - diff --git a/eav_ng/tests/__init__.py b/tests/__init__.py similarity index 100% rename from eav_ng/tests/__init__.py rename to tests/__init__.py diff --git a/eav_ng/tests/models.py b/tests/models.py similarity index 100% rename from eav_ng/tests/models.py rename to tests/models.py diff --git a/eav_ng/tests/tests.py b/tests/tests.py similarity index 100% rename from eav_ng/tests/tests.py rename to tests/tests.py diff --git a/urls.py b/urls.py deleted file mode 100644 index 670b017..0000000 --- a/urls.py +++ /dev/null @@ -1,17 +0,0 @@ -from django.conf.urls.defaults import * - -# Uncomment the next two lines to enable the admin: -from django.contrib import admin -admin.autodiscover() - -urlpatterns = patterns('', - # Example: - # (r'^myeav/', include('myeav.foo.urls')), - - # Uncomment the admin/doc line below and add 'django.contrib.admindocs' - # to INSTALLED_APPS to enable admin documentation: - # (r'^admin/doc/', include('django.contrib.admindocs.urls')), - - # Uncomment the next line to enable the admin: - (r'^admin/', include(admin.site.urls)), -) diff --git a/eav_ng/utils.py b/utils.py similarity index 100% rename from eav_ng/utils.py rename to utils.py diff --git a/eav_ng/views.py b/views.py similarity index 100% rename from eav_ng/views.py rename to views.py