Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Added DictField and support for HStoreField.#2451

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
lovelydinosaur merged 1 commit intomasterfromdict-field
Jan 23, 2015
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletiondocs/api-guide/fields.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -380,7 +380,7 @@ A field class that validates a list of objects.

**Signature**: `ListField(child)`

- `child` - A field instance that should be used for validating the objects in the list.
- `child` - A field instance that should be used for validating the objects in the list. If this argument is not provided then objects in the list will not be validated.

For example, to validate a list of integers you might use something like the following:

Expand All@@ -395,6 +395,23 @@ The `ListField` class also supports a declarative style that allows you to write

We can now reuse our custom `StringListField` class throughout our application, without having to provide a `child` argument to it.

## DictField

A field class that validates a dictionary of objects. The keys in `DictField` are always assumed to be string values.

**Signature**: `DictField(child)`

- `child` - A field instance that should be used for validating the values in the dictionary. If this argument is not provided then values in the mapping will not be validated.

For example, to create a field that validates a mapping of strings to strings, you would write something like this:

document = DictField(child=CharField())

You can also use the declarative style, as with `ListField`. For example:

class DocumentField(DictField):
child = CharField()

---

# Miscellaneous fields
Expand Down
7 changes: 7 additions & 0 deletionsrest_framework/compat.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -58,6 +58,13 @@ def total_seconds(timedelta):
from django.http import HttpResponse as HttpResponseBase


# contrib.postgres only supported from 1.8 onwards.
try:
from django.contrib.postgres import fields as postgres_fields
except ImportError:
postgres_fields = None


# request only provides `resolver_match` from 1.5 onwards.
def get_resolver_match(request):
try:
Expand Down
59 changes: 57 additions & 2 deletionsrest_framework/fields.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1132,16 +1132,28 @@ def to_internal_value(self, data):

# Composite field types...

class _UnvalidatedField(Field):
def __init__(self, *args, **kwargs):
super(_UnvalidatedField, self).__init__(*args, **kwargs)
self.allow_blank = True
self.allow_null = True

def to_internal_value(self, data):
return data

def to_representation(self, value):
return value


class ListField(Field):
child =None
child =_UnvalidatedField()
initial = []
default_error_messages = {
'not_a_list': _('Expected a list of items but got type `{input_type}`')
}

def __init__(self, *args, **kwargs):
self.child = kwargs.pop('child', copy.deepcopy(self.child))
assert self.child is not None, '`child` is a required argument.'
assert not inspect.isclass(self.child), '`child` has not been instantiated.'
super(ListField, self).__init__(*args, **kwargs)
self.child.bind(field_name='', parent=self)
Expand DownExpand Up@@ -1170,6 +1182,49 @@ def to_representation(self, data):
return [self.child.to_representation(item) for item in data]


class DictField(Field):
child = _UnvalidatedField()
initial = []
default_error_messages = {
'not_a_dict': _('Expected a dictionary of items but got type `{input_type}`')
}

def __init__(self, *args, **kwargs):
self.child = kwargs.pop('child', copy.deepcopy(self.child))
assert not inspect.isclass(self.child), '`child` has not been instantiated.'
super(DictField, self).__init__(*args, **kwargs)
self.child.bind(field_name='', parent=self)

def get_value(self, dictionary):
# We override the default field access in order to support
# lists in HTML forms.
if html.is_html_input(dictionary):
return html.parse_html_list(dictionary, prefix=self.field_name)
return dictionary.get(self.field_name, empty)

def to_internal_value(self, data):
"""
Dicts of native values <- Dicts of primitive datatypes.
"""
if html.is_html_input(data):
data = html.parse_html_dict(data)
if not isinstance(data, dict):
self.fail('not_a_dict', input_type=type(data).__name__)
return dict([
(six.text_type(key), self.child.run_validation(value))
for key, value in data.items()
])

def to_representation(self, value):
"""
List of object instances -> List of dicts of primitive datatypes.
"""
return dict([
(six.text_type(key), self.child.to_representation(val))
for key, val in value.items()
])


# Miscellaneous field types...

class ReadOnlyField(Field):
Expand Down
8 changes: 7 additions & 1 deletionrest_framework/serializers.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@
from django.db import models
from django.db.models.fields import FieldDoesNotExist, Field as DjangoField
from django.utils.translation import ugettext_lazy as _
from rest_framework.compat import unicode_to_repr
from rest_framework.compat importpostgres_fields,unicode_to_repr
from rest_framework.utils import model_meta
from rest_framework.utils.field_mapping import (
get_url_kwargs, get_field_kwargs,
Expand DownExpand Up@@ -1137,6 +1137,12 @@ class Meta:
if hasattr(models, 'UUIDField'):
ModelSerializer._field_mapping[models.UUIDField] = UUIDField

if postgres_fields:
class CharMappingField(DictField):
child = CharField()

ModelSerializer._field_mapping[postgres_fields.HStoreField] = CharMappingField


class HyperlinkedModelSerializer(ModelSerializer):
"""
Expand Down
51 changes: 50 additions & 1 deletiontests/test_fields.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1047,7 +1047,7 @@ class TestValidImageField(FieldValues):

class TestListField(FieldValues):
"""
Values for `ListField`.
Values for `ListField` with IntegerField as child.
"""
valid_inputs = [
([1, 2, 3], [1, 2, 3]),
Expand All@@ -1064,6 +1064,55 @@ class TestListField(FieldValues):
field = serializers.ListField(child=serializers.IntegerField())


class TestUnvalidatedListField(FieldValues):
"""
Values for `ListField` with no `child` argument.
"""
valid_inputs = [
([1, '2', True, [4, 5, 6]], [1, '2', True, [4, 5, 6]]),
]
invalid_inputs = [
('not a list', ['Expected a list of items but got type `str`']),
]
outputs = [
([1, '2', True, [4, 5, 6]], [1, '2', True, [4, 5, 6]]),
]
field = serializers.ListField()


class TestDictField(FieldValues):
"""
Values for `ListField` with CharField as child.
"""
valid_inputs = [
({'a': 1, 'b': '2', 3: 3}, {'a': '1', 'b': '2', '3': '3'}),
]
invalid_inputs = [
({'a': 1, 'b': None}, ['This field may not be null.']),
('not a dict', ['Expected a dictionary of items but got type `str`']),
]
outputs = [
({'a': 1, 'b': '2', 3: 3}, {'a': '1', 'b': '2', '3': '3'}),
]
field = serializers.DictField(child=serializers.CharField())


class TestUnvalidatedDictField(FieldValues):
"""
Values for `ListField` with no `child` argument.
"""
valid_inputs = [
({'a': 1, 'b': [4, 5, 6], 1: 123}, {'a': 1, 'b': [4, 5, 6], '1': 123}),
]
invalid_inputs = [
('not a dict', ['Expected a dictionary of items but got type `str`']),
]
outputs = [
({'a': 1, 'b': [4, 5, 6]}, {'a': 1, 'b': [4, 5, 6]}),
]
field = serializers.DictField()


# Tests for FieldField.
# ---------------------

Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp