Compat fixes

This commit is contained in:
Tom Christie 2014-09-10 16:57:22 +01:00
parent 01c8c0cad9
commit 80ba047347
4 changed files with 36 additions and 24 deletions

View File

@ -110,8 +110,18 @@ def get_concrete_model(model_cls):
return model_cls return model_cls
# View._allowed_methods only present from 1.5 onwards
if django.VERSION >= (1, 5):
from django.views.generic import View
else:
from django.views.generic import View as DjangoView
class View(DjangoView):
def _allowed_methods(self):
return [m.upper() for m in self.http_method_names if hasattr(self, m)]
# PATCH method is not implemented by Django # PATCH method is not implemented by Django
from django.views.generic import View
if 'patch' not in View.http_method_names: if 'patch' not in View.http_method_names:
View.http_method_names = View.http_method_names + ['patch'] View.http_method_names = View.http_method_names + ['patch']

View File

@ -266,8 +266,8 @@ class BooleanField(Field):
default_error_messages = { default_error_messages = {
'invalid': _('`{input}` is not a valid boolean.') 'invalid': _('`{input}` is not a valid boolean.')
} }
TRUE_VALUES = {'t', 'T', 'true', 'True', 'TRUE', '1', 1, True} TRUE_VALUES = set(('t', 'T', 'true', 'True', 'TRUE', '1', 1, True))
FALSE_VALUES = {'f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False} FALSE_VALUES = set(('f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False))
def get_value(self, dictionary): def get_value(self, dictionary):
if html.is_html_input(dictionary): if html.is_html_input(dictionary):
@ -678,16 +678,16 @@ class ChoiceField(Field):
for item in choices for item in choices
] ]
if all(pairs): if all(pairs):
self.choices = {key: display_value for key, display_value in choices} self.choices = dict([(key, display_value) for key, display_value in choices])
else: else:
self.choices = {item: item for item in choices} self.choices = dict([(item, item) for item in choices])
# Map the string representation of choices to the underlying value. # Map the string representation of choices to the underlying value.
# Allows us to deal with eg. integer choices while supporting either # Allows us to deal with eg. integer choices while supporting either
# integer or string input, but still get the correct datatype out. # integer or string input, but still get the correct datatype out.
self.choice_strings_to_values = { self.choice_strings_to_values = dict([
str(key): key for key in self.choices.keys() (str(key), key) for key in self.choices.keys()
} ])
super(ChoiceField, self).__init__(**kwargs) super(ChoiceField, self).__init__(**kwargs)

View File

@ -14,7 +14,8 @@ from django.core import validators
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db import models from django.db import models
from django.utils import six from django.utils import six
from collections import namedtuple, OrderedDict from django.utils.datastructures import SortedDict
from collections import namedtuple
from rest_framework.compat import clean_manytomany_helptext from rest_framework.compat import clean_manytomany_helptext
from rest_framework.fields import empty, set_value, Field, SkipField from rest_framework.fields import empty, set_value, Field, SkipField
from rest_framework.settings import api_settings from rest_framework.settings import api_settings
@ -91,10 +92,10 @@ class BaseSerializer(Field):
if self.instance is not None: if self.instance is not None:
self._data = self.to_primative(self.instance) self._data = self.to_primative(self.instance)
elif self._initial_data is not None: elif self._initial_data is not None:
self._data = { self._data = dict([
field_name: field.get_value(self._initial_data) (field_name, field.get_value(self._initial_data))
for field_name, field in self.fields.items() for field_name, field in self.fields.items()
} ])
else: else:
self._data = self.get_initial() self._data = self.get_initial()
return self._data return self._data
@ -137,7 +138,7 @@ class SerializerMetaclass(type):
if hasattr(base, 'base_fields'): if hasattr(base, 'base_fields'):
fields = list(base.base_fields.items()) + fields fields = list(base.base_fields.items()) + fields
return OrderedDict(fields) return SortedDict(fields)
def __new__(cls, name, bases, attrs): def __new__(cls, name, bases, attrs):
attrs['base_fields'] = cls._get_fields(bases, attrs) attrs['base_fields'] = cls._get_fields(bases, attrs)
@ -180,10 +181,10 @@ class Serializer(BaseSerializer):
field.bind(field_name, self, root) field.bind(field_name, self, root)
def get_initial(self): def get_initial(self):
return { return dict([
field.field_name: field.get_initial() (field.field_name, field.get_initial())
for field in self.fields.values() for field in self.fields.values()
} ])
def get_value(self, dictionary): def get_value(self, dictionary):
# We override the default field access in order to support # We override the default field access in order to support
@ -222,14 +223,14 @@ class Serializer(BaseSerializer):
try: try:
return self.validate(ret) return self.validate(ret)
except ValidationError, exc: except ValidationError as exc:
raise ValidationError({'non_field_errors': exc.messages}) raise ValidationError({'non_field_errors': exc.messages})
def to_primative(self, instance): def to_primative(self, instance):
""" """
Object instance -> Dict of primitive datatypes. Object instance -> Dict of primitive datatypes.
""" """
ret = OrderedDict() ret = SortedDict()
fields = [field for field in self.fields.values() if not field.write_only] fields = [field for field in self.fields.values() if not field.write_only]
for field in fields: for field in fields:
@ -368,7 +369,7 @@ class ModelSerializer(Serializer):
# If `fields` is set on the `Meta` class, # If `fields` is set on the `Meta` class,
# then use only those fields, and in that order. # then use only those fields, and in that order.
if self.opts.fields: if self.opts.fields:
fields = OrderedDict([ fields = SortedDict([
(key, fields[key]) for key in self.opts.fields (key, fields[key]) for key in self.opts.fields
]) ])
@ -379,7 +380,7 @@ class ModelSerializer(Serializer):
Return all the fields that should be serialized for the model. Return all the fields that should be serialized for the model.
""" """
info = modelinfo.get_field_info(self.opts.model) info = modelinfo.get_field_info(self.opts.model)
ret = OrderedDict() ret = SortedDict()
serializer_url_field = self.get_url_field() serializer_url_field = self.get_url_field()
if serializer_url_field: if serializer_url_field:

View File

@ -2,9 +2,10 @@
Helper functions for returning the field information that is associated Helper functions for returning the field information that is associated
with a model class. with a model class.
""" """
from collections import namedtuple, OrderedDict from collections import namedtuple
from django.db import models from django.db import models
from django.utils import six from django.utils import six
from django.utils.datastructures import SortedDict
import inspect import inspect
FieldInfo = namedtuple('FieldResult', ['pk', 'fields', 'forward_relations', 'reverse_relations']) FieldInfo = namedtuple('FieldResult', ['pk', 'fields', 'forward_relations', 'reverse_relations'])
@ -45,12 +46,12 @@ def get_field_info(model):
pk = pk.rel.to._meta.pk pk = pk.rel.to._meta.pk
# Deal with regular fields. # Deal with regular fields.
fields = OrderedDict() fields = SortedDict()
for field in [field for field in opts.fields if field.serialize and not field.rel]: for field in [field for field in opts.fields if field.serialize and not field.rel]:
fields[field.name] = field fields[field.name] = field
# Deal with forward relationships. # Deal with forward relationships.
forward_relations = OrderedDict() forward_relations = SortedDict()
for field in [field for field in opts.fields if field.serialize and field.rel]: for field in [field for field in opts.fields if field.serialize and field.rel]:
forward_relations[field.name] = RelationInfo( forward_relations[field.name] = RelationInfo(
field=field, field=field,
@ -71,7 +72,7 @@ def get_field_info(model):
) )
# Deal with reverse relationships. # Deal with reverse relationships.
reverse_relations = OrderedDict() reverse_relations = SortedDict()
for relation in opts.get_all_related_objects(): for relation in opts.get_all_related_objects():
accessor_name = relation.get_accessor_name() accessor_name = relation.get_accessor_name()
reverse_relations[accessor_name] = RelationInfo( reverse_relations[accessor_name] = RelationInfo(