Package: django-lookup-tables
Django Lookup TablesEfficient 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.IMPORTANTThis software is still pre-release. Upgrades from one version to the next may create unstabilities in your project. If you have used any version prior to1.0.0, please read theRelease Notes for Beta Versions.InstallationInstall the package:$pipinstalldjango-lookup-tablesAdd it to your installed apps:INSTALLED_APPS=(...'lookup_tables',...)UsageThe 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:fromdjango.dbimportmodelsfromlookup_tables.fieldsimportLookupTableItemFieldCHOICES=(('draft','draft'),('published','published'))classPost(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:fromdjango.dbimportmodelsfromlookup_tables.modelsimportAbsractLookupTablefromlookup_tables.fieldsimportLookupFieldclassPostState(AbstractLookupTable):passclassPost(models.Model):title=models.CharField(max_length=100)state=LookupField(PostState)This will create a lookup table calledPostStatethat can be administered by staff users. You can now set this field to any value from thePostStatemodel.If you register your model in the app'sadmin.py:fromdjango.contribimportadminfromlookup_tables.adminimportLookupAdminfrom.modelsimportPostState@admin.register(PostState)classPostStateAdmin(LookupAdmin):pass... you will be able to modify the values in the table through the "Post State" link in the Django admin.django-lookup-tablesintegrates properly with forms out of the box, so all UI naturally gets up-to-date selection lists just like if you were using aCharFieldwith 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-Sortable2If you havedjango-admin-sortable2installed, you can take advantage of it's UI enhancements by configuringdjango-lookup-tablesto use it. In yoursettings.py:INSTALLED_APPS=(...'adminsortable2','lookup_tables',...)LOOKUP_TABLES={'USE_ADMIN_SORTABLE2':True,}Using with Django REST FrameworkFields on models will render the same wayCharFielddoes if you use thedrf_fields.LookupSerializerFieldfield on your serializer like so:classPostSerializer(serializers.ModelSerializer):classMeta:fields=('id','title','state')state=LookupSerializerField(PostState)By default, the field will send theidof theLookupTableItem. If you instead want to send thenameproperty, addDRF_REPRESENTATION_NAME_NOT_IDto yoursettings.py:LOOKUP_TABLES={# ...'DRF_REPRESENTATION_NAME_NOT_ID':True,# ...}The HTML UI provided by DRF will populate dropdowns, and theOPTIONSresponse handler will supply all key/value pairs available for the field:OPTIONS/api/posts/1/HTTP200OKAllow:GET,PUT,PATCH,DELETE,HEAD,OPTIONSContent-Type:application/jsonVary: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"}]}}}}Sample AppYou can see a sample app using these fields buy running the following:$pythonmanage.pymigrate
$pythonmanage.pyloaddatafixtures/base.json
$pythonmanage.pyrunserverThis app has the following endpoints:/admin/
/api/mymodel/
/api/mymodel/<id>/The username for the admin user isadmin, and the password ispass.ContributingI 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.