From 80ba0473473501968154c5cc5dd5922e53d96a70 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 10 Sep 2014 16:57:22 +0100 Subject: [PATCH] Compat fixes --- rest_framework/compat.py | 12 +++++++++++- rest_framework/fields.py | 14 +++++++------- rest_framework/serializers.py | 25 +++++++++++++------------ rest_framework/utils/modelinfo.py | 9 +++++---- 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/rest_framework/compat.py b/rest_framework/compat.py index 70b38df98..7c05bed9c 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -110,8 +110,18 @@ def get_concrete_model(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 -from django.views.generic import View if 'patch' not in View.http_method_names: View.http_method_names = View.http_method_names + ['patch'] diff --git a/rest_framework/fields.py b/rest_framework/fields.py index e71dce1df..3ec28908d 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -266,8 +266,8 @@ class BooleanField(Field): default_error_messages = { 'invalid': _('`{input}` is not a valid boolean.') } - TRUE_VALUES = {'t', 'T', 'true', 'True', 'TRUE', '1', 1, True} - FALSE_VALUES = {'f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False} + TRUE_VALUES = set(('t', 'T', 'true', 'True', 'TRUE', '1', 1, True)) + FALSE_VALUES = set(('f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False)) def get_value(self, dictionary): if html.is_html_input(dictionary): @@ -678,16 +678,16 @@ class ChoiceField(Field): for item in choices ] 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: - 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. # Allows us to deal with eg. integer choices while supporting either # integer or string input, but still get the correct datatype out. - self.choice_strings_to_values = { - str(key): key for key in self.choices.keys() - } + self.choice_strings_to_values = dict([ + (str(key), key) for key in self.choices.keys() + ]) super(ChoiceField, self).__init__(**kwargs) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 459f8a8ce..13e579398 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -14,7 +14,8 @@ from django.core import validators from django.core.exceptions import ValidationError from django.db import models 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.fields import empty, set_value, Field, SkipField from rest_framework.settings import api_settings @@ -91,10 +92,10 @@ class BaseSerializer(Field): if self.instance is not None: self._data = self.to_primative(self.instance) elif self._initial_data is not None: - self._data = { - field_name: field.get_value(self._initial_data) + self._data = dict([ + (field_name, field.get_value(self._initial_data)) for field_name, field in self.fields.items() - } + ]) else: self._data = self.get_initial() return self._data @@ -137,7 +138,7 @@ class SerializerMetaclass(type): if hasattr(base, 'base_fields'): fields = list(base.base_fields.items()) + fields - return OrderedDict(fields) + return SortedDict(fields) def __new__(cls, name, bases, attrs): attrs['base_fields'] = cls._get_fields(bases, attrs) @@ -180,10 +181,10 @@ class Serializer(BaseSerializer): field.bind(field_name, self, root) def get_initial(self): - return { - field.field_name: field.get_initial() + return dict([ + (field.field_name, field.get_initial()) for field in self.fields.values() - } + ]) def get_value(self, dictionary): # We override the default field access in order to support @@ -222,14 +223,14 @@ class Serializer(BaseSerializer): try: return self.validate(ret) - except ValidationError, exc: + except ValidationError as exc: raise ValidationError({'non_field_errors': exc.messages}) def to_primative(self, instance): """ Object instance -> Dict of primitive datatypes. """ - ret = OrderedDict() + ret = SortedDict() fields = [field for field in self.fields.values() if not field.write_only] for field in fields: @@ -368,7 +369,7 @@ class ModelSerializer(Serializer): # If `fields` is set on the `Meta` class, # then use only those fields, and in that order. if self.opts.fields: - fields = OrderedDict([ + fields = SortedDict([ (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. """ info = modelinfo.get_field_info(self.opts.model) - ret = OrderedDict() + ret = SortedDict() serializer_url_field = self.get_url_field() if serializer_url_field: diff --git a/rest_framework/utils/modelinfo.py b/rest_framework/utils/modelinfo.py index c0513886c..a7a0346c2 100644 --- a/rest_framework/utils/modelinfo.py +++ b/rest_framework/utils/modelinfo.py @@ -2,9 +2,10 @@ Helper functions for returning the field information that is associated with a model class. """ -from collections import namedtuple, OrderedDict +from collections import namedtuple from django.db import models from django.utils import six +from django.utils.datastructures import SortedDict import inspect FieldInfo = namedtuple('FieldResult', ['pk', 'fields', 'forward_relations', 'reverse_relations']) @@ -45,12 +46,12 @@ def get_field_info(model): pk = pk.rel.to._meta.pk # Deal with regular fields. - fields = OrderedDict() + fields = SortedDict() for field in [field for field in opts.fields if field.serialize and not field.rel]: fields[field.name] = field # 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]: forward_relations[field.name] = RelationInfo( field=field, @@ -71,7 +72,7 @@ def get_field_info(model): ) # Deal with reverse relationships. - reverse_relations = OrderedDict() + reverse_relations = SortedDict() for relation in opts.get_all_related_objects(): accessor_name = relation.get_accessor_name() reverse_relations[accessor_name] = RelationInfo(