Skip to content

Commit

Permalink
Merge pull request #18 from seawolf42/feature/choose-between-name-and…
Browse files Browse the repository at this point in the history
…-id-in-serializer

Feature/choose between name and id in serializer
  • Loading branch information
seawolf42 committed Jun 15, 2018
2 parents aefae13 + 9815a6e commit 6702530
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 14 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@ class PostSerializer(serializers.ModelSerializer):
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`:

```python
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:

```json
Expand Down
15 changes: 15 additions & 0 deletions lookup_tables/conf.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
import os
import sys

from django.conf import settings

_SETTINGS = getattr(settings, 'LOOKUP_TABLES', {})

USE_ADMIN_SORTABLE2 = _SETTINGS.get('USE_ADMIN_SORTABLE2', False)
DRF_REPRESENTATION_NAME_NOT_ID = _SETTINGS.get('DRF_REPRESENTATION_NAME_NOT_ID', False)

_IGNORE_INIT_RESET_KEY = 'LOOKUP_TABLES_DRF_FIELD_INIT_NO_RESET'

if _IGNORE_INIT_RESET_KEY in os.environ:
IGNORE_INIT_RESET = os.environ[_IGNORE_INIT_RESET_KEY].lower() in ('1', 'true')
elif len(sys.argv) > 1 and sys.argv[0].endswith('manage.py') and sys.argv[1] != 'runserver':
IGNORE_INIT_RESET = True
else:
IGNORE_INIT_RESET = False

del _IGNORE_INIT_RESET_KEY
17 changes: 4 additions & 13 deletions lookup_tables/drf_fields.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
import os
import sys

from lookup_tables.models import LookupTableItem
from rest_framework import fields
import six

from . import conf

_IGNORE_INIT_RESET_KEY = 'LOOKUP_TABLES_DRF_FIELD_INIT_NO_RESET'

if _IGNORE_INIT_RESET_KEY in os.environ:
_IGNORE_INIT_RESET = os.environ[_IGNORE_INIT_RESET_KEY].lower() in ('1', 'true')
elif len(sys.argv) > 1 and sys.argv[0].endswith('manage.py') and sys.argv[1] != 'runserver':
_IGNORE_INIT_RESET = True
else:
_IGNORE_INIT_RESET = False

del _IGNORE_INIT_RESET_KEY
_IGNORE_INIT_RESET = conf.IGNORE_INIT_RESET
_REPR_NAME = conf.DRF_REPRESENTATION_NAME_NOT_ID


class LookupTableItemSerializerField(fields.ChoiceField):
Expand All @@ -42,7 +33,7 @@ def to_internal_value(self, data):
def to_representation(self, value):
if value is None:
return value
return super(LookupTableItemSerializerField, self).to_representation(value.name)
return super(LookupTableItemSerializerField, self).to_representation(value.name if _REPR_NAME else value.id)

def iter_options(self):
"""
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

setup(
name='django-lookup-tables',
version='0.12.3',
version='0.12.4',
packages=find_packages(),
include_package_data=True,
license='MIT License',
Expand Down
1 change: 1 addition & 0 deletions tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

LOOKUP_TABLES = {
'USE_ADMIN_SORTABLE2': False,
# 'DRF_REPRESENTATION_NAME_NOT_ID': True,
}

if LOOKUP_TABLES['USE_ADMIN_SORTABLE2']:
Expand Down
16 changes: 16 additions & 0 deletions tests/test_drf_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ def test_init(self, mock_reset_choices, mock_parent_init):
self.assertEqual(item._table_ref, strings[0])
self.assertEqual(item.choices, None)

@mock.patch('rest_framework.fields.ChoiceField.__init__')
@mock.patch('lookup_tables.drf_fields.LookupTableItemSerializerField._reset_choices')
@mock.patch('lookup_tables.drf_fields._IGNORE_INIT_RESET')
def test_init_no_reset(self, mock_ignore_reset_setting, mock_reset_choices, mock_parent_init):
item = LookupTableItemSerializerField(strings[0], x=strings[-1], y=strings[-2])
mock_parent_init.assert_called_once_with([], x=strings[-1], y=strings[-2])
mock_reset_choices.assert_not_called()
self.assertEqual(item._table_ref, strings[0])
self.assertEqual(item.choices, None)

def test_to_internal_value_handles_empty_reply(self):
item = LookupTableItemSerializerField(strings[0], allow_blank=True)
self.assertIsNone(item.to_internal_value(''))
Expand Down Expand Up @@ -66,6 +76,12 @@ def test_to_internal_value_invalid_table_id(self, mock_lti):
item.to_internal_value('1')

def test_to_representation(self):
item = LookupTableItemSerializerField(strings[0])
self.assertEqual(item.to_representation(MockLTI(1)), 1)

@mock.patch('lookup_tables.drf_fields._REPR_NAME')
def test_to_representation_name_not_id(self, mock_repr_setting):
mock_repr_setting.return_value = True
item = LookupTableItemSerializerField(strings[0])
self.assertEqual(item.to_representation(MockLTI(1)), '1')

Expand Down

0 comments on commit 6702530

Please sign in to comment.