Skip to main content

Combine all lookup tables into a single unified system.

Project description

Django Lookup Tables

Efficient storage and management of lookup tables used throughout an app.

Note: This package is a work in progress (that's why it's not yet at version 1.0). I am active seeking contributions to help with making it more usable, see "Contributing" below.

Installation

Install the package:

$ pip install django-lookup-tables

Add it to your installed apps:

INSTALLED_APPS = (
    ...
    'lookup_tables',
    ...
)

Usage

The primary use case for lookup tables is to create user-managed lists of options for models to choose from. Consider a model with a field called, for instance, state:

from django.db import models
from lookup_tables.fields import LookupTableItemField

CHOICES = (('draft', 'draft'), ('published', 'published'))

class Post(models.Model):
    title = models.CharField(max_length=100)
    state = models.CharField(choices=CHOICES)

While this is easy to build, changing the choices list requires rebuilding and redeploying your application.

The above model could instead be written as:

from django.db import models
from lookup_tables.fields import LookupTableItemField

class Post(models.Model):
    title = models.CharField(max_length=100)
    state = LookupTableItemField(table_ref='post-state')

This will create a lookup table called "post-state" that has a single option, '<DEFAULT>'. You can now set this field to any value from the LookupTableItems model that references the LookupTable.objects.get(table_ref='post-state') table.

In the admin you will see an entry for 'Lookup Tables'. Here you can manage tables and their associated values. Note that the automatically-generated '<DEFAULT>' item can be renamed or removed; this is just created so that the table is not empty on first use.

django-lookup-tables integrates properly with forms out of the box, so all UI naturally gets up-to-date selection lists just like if you were using a CharField with a choices enum or tuple list.

Each table has an arbitrary list of items. You can order them by setting the "Sort Order" field to any positive integer.

Using with Admin-Sortable2

If you have django-admin-sortable2 installed, you can take advantage of it's UI enhancements by configuring django-lookup-tables to use it. In your settings.py:

INSTALLED_APPS = (
    ...
    'adminsortable2',
    'lookup_tables',
    ...
)

LOOKUP_TABLES = {
    'USE_ADMIN_SORTABLE2': True,
}

Using with Django REST Framework

Fields on models will render the same way CharField does if you use the drf_fields.LookupTableItemSerializerField field on your serializer like so:

class PostSerializer(serializers.ModelSerializer):

    class Meta:
        fields = ('id', 'title', 'state')

    state = LookupTableItemSerializerField(table_ref='post-state')

By default, the field will send the id of the LookupTableItem. If you instead want to send the name property, add DRF_REPRESENTATION_NAME_NOT_ID to your settings.py:

LOOKUP_TABLES = {
    # ...
    'DRF_REPRESENTATION_NAME_NOT_ID': True,
    # ...
}

The HTML UI provided by DRF will populate dropdowns, and the OPTIONS response handler will supply all key/value pairs available for the field:

OPTIONS /api/posts/1/
HTTP 200 OK
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "name": "Post Instance",
    "description": "",
    "renders": [
        "application/json",
        "text/html"
    ],
    "parses": [
        "application/json",
        "application/x-www-form-urlencoded",
        "multipart/form-data"
    ],
    "actions": {
        "PUT": {
            "id": {
                "type": "integer",
                "required": false,
                "read_only": true,
                "label": "ID"
            },
            "title": {
                "type": "string",
                "required": true,
                "read_only": false,
                "label": "Name",
                "max_length": 200
            },
            "state": {
                "type": "choice",
                "required": true,
                "read_only": false,
                "label": "State",
                "choices": [
                    {
                        "value": 14,
                        "display_name": "Draft"
                    },
                    {
                        "value": 18,
                        "display_name": "Published"
                    }
                ]
            }
        }
    }
}

NOTE: If you are using the LookupTableItemSerializerField on any serializer, you need to disable an init hook for all management commands except runserver. Failure to do so will result in an error similar to the following:

django.db.utils.ProgrammingError: relation "lookup_tables_lookuptableitem" does not exist
LINE 1: ..."lookup_tables_lookuptableitem"."sort_order" FROM "lookup_ta...

Disabling the init-hook can be controlled by putting the following in your manage.py script:

os.environ.setdefault('LOOKUP_TABLES_DRF_FIELD_INIT_NO_RESET', str(sys.argv[1] != 'runserver'))

Note additionally that this setting should not be disabled in your wsgi application.

Sample App

You can see a sample app using these fields buy running the following:

$ python manage.py migrate
$ python manage.py loaddata fixtures/base.json
$ python manage.py runserver

This app has the following endpoints:

/admin/
/api/mymodel/
/api/mymodel/<id>/

The username for the admin user is admin, and the password is pass.

Contributing

I am actively seeking contributions to this package. Check the "Issues" section of the repository for my current hit list.

If you have suggestions for other features I am open to hearing them. Use the "Issues" section of the repository to start a conversation.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-lookup-tables-0.13.0.tar.gz (230.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_lookup_tables-0.13.0-py3-none-any.whl (17.7 kB view details)

Uploaded Python 3

File details

Details for the file django-lookup-tables-0.13.0.tar.gz.

File metadata

File hashes

Hashes for django-lookup-tables-0.13.0.tar.gz
Algorithm Hash digest
SHA256 713ae8ff790b3e38cd434130284afb9c5fb999169697cd07e0545658bd46804a
MD5 ba262b1fa392a796b9bf7c86b0d82eef
BLAKE2b-256 33df6528e48a8d0cf63839129ae64ba22617256c0f05056a6ea25c8d34ef19be

See more details on using hashes here.

File details

Details for the file django_lookup_tables-0.13.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_lookup_tables-0.13.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e467f78527c75422d317cfcf70f6153aa22de4bf59232cca2ba2a01c9f74fe20
MD5 323226f9359dc78199f0de775f26d3f2
BLAKE2b-256 e71626a566750b9936009cf4d0216d48efad3e60e1d3fcc1465296993a281e35

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page