Reference data

Lookup Lists allow us to create or reference canonical lists of available terminology as a foreign key, while also allowing synonymous terms, and a free text override.

Core referencedata

By default, Opal will install some lookuplists for common things such as countries, drugs, conditions, and symptoms amongst others. The data for these is found in the opal.core.referencedata package.

Adding a lookup list

Lookup lists are subclasses of opal.core.lookuplists.LookupList. Typically, a specific named lookup list will not need to do anything other than define a class that inherits from the base class.

The custom field type opal.core.fields.ForeignKeyOrFreeText allows you to build interfaces that cater for synonyms, and also allow the user to enter a free text string that is not in the lookup list.

# yourapp.models
from django.db import models
from opal.core import lookuplists
from opal.core.fields import ForeignKeyOrFreeText
from opal.models import EpisodeSubrecord

class TreatmentType(lookuplists.LookupList): pass

class Treatment(EpisodeSubrecord):
    treatment = ForeignKeyOrFreeText(TreatmentType)
    notes     = models.CharField(max_length=200)

When you create your lookup list, you are creating a new model, so you will need a new migration to accompany it.

$ python manage.py schemamigration --atuo yourapp
$ python manage.py migrate yourapp

The lookup list will automatically be added to the admin, where you can manually add entries.

Reference data JSON API

Reference data is available over the Opal JSON API.

You may either load all lookuplists at once via the /api/v0.1/referencedata/ endpoint, or individual lookuplists by name - for example all diagnoses from /api/v0.1/referencedata/diagnosis/.

The reference data API also loads all synonyms in a flat list - the conversion of synonyms to their canonical form is handled by the save mechanism of subrecords using ForeignKeyOrFreeText fields.

Working with reference data on the front end

The Angular service Referencedata can be used to fetch all lookuplists at once - for instance loaded in the Angular routing for a controller in your application

when('/my/route', {
    controller: 'MyCtrl',
    resolve: {
           referencedata: function(Referencedata){ return Referencedata; }
         }
    }

Lookuplists will then be available either as properties of the referencedata object.

Using referencedata in forms

The Opal form templatetag library allow us to easily incorporate referencedata into the forms we build, either by detecting their use automatically when we have ForeignKeyOrFreeText fields, or explicitly by passing an argument.

{% load forms %}
{% input field="Diagnosis.condition" %}
{% select label="List of Conditions" lookuplist="referencedata.diagnosis" %}

Providing data for lookuplists

Reference data can be provided at application or plugin level in a file named lookuplists.json found in the {{ app_or_plugin }}/data/lookuplists directory. This data should be in the Opal JSON format. The name value of each lookuplist should be the return value of that lookuplist's get_api_name() method (otherwise they will fail to load), these can be found via Schemas

{
    "name_of_lookuplist": [
        {
            "name": "Value of lookuplist item",
            "synonyms": ["Synonym 1",]

        },
    ]
}

Once this data is stored in the lookuplists file, we can batch load it into our application with the command

python manage.py load_lookup_lists

Coding lookuplist values

Often applications wish to use coded reference data from a pre-existing terminology such as SNOMED.

This can be easily accomplished by adding coding values to the lookuplist JSON data.

{
    "name_of_lookuplist": [
        {
            "name": "Value of lookuplist item",
            "synonyms": ["Synonym 1",],
            "coding": {
                "system": "SNOMED CT",
                "code": "3428473"
            }
        },
    ]
}

Management commands

Opal ships with some management commands for importing and exporting lookup lists

dump_lookup_lists

Prints all loockuplists as JSON to stdout.

When the --many-files argument is passd, the command will write each installed lookup list to a separate file in the ./data/lookuplists directory of the application.

load_lookup_lists

Loads lookup lists from all plugins/apps in the Opal JSON format. The lookup lists are expected to be in {{ app }}/data/lookuplists/lookuplists.json

Optionally you can pass in an explicit filename with the -f argument.

delete_all_lookup_lists

Deletes all currently lookuplist values and related synonyms