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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for django-lookup-tables-0.13.0.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 713ae8ff790b3e38cd434130284afb9c5fb999169697cd07e0545658bd46804a |
|
MD5 | ba262b1fa392a796b9bf7c86b0d82eef |
|
BLAKE2b-256 | 33df6528e48a8d0cf63839129ae64ba22617256c0f05056a6ea25c8d34ef19be |
Hashes for django_lookup_tables-0.13.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | e467f78527c75422d317cfcf70f6153aa22de4bf59232cca2ba2a01c9f74fe20 |
|
MD5 | 323226f9359dc78199f0de775f26d3f2 |
|
BLAKE2b-256 | e71626a566750b9936009cf4d0216d48efad3e60e1d3fcc1465296993a281e35 |