Commit 968f4a5c by Marko Tibold

Merge branch 'custom-serializer-form-class' of…

Merge branch 'custom-serializer-form-class' of https://github.com/ludwigkraatz/django-rest-framework into mergebranch#390

Conflicts:
	rest_framework/fields.py
	rest_framework/renderers.py
Manually solved
parents 60def44e 5cd64cc5
...@@ -10,6 +10,7 @@ from django.core import validators ...@@ -10,6 +10,7 @@ from django.core import validators
from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.core.urlresolvers import resolve, get_script_prefix from django.core.urlresolvers import resolve, get_script_prefix
from django.conf import settings from django.conf import settings
from django import forms
from django.forms import widgets from django.forms import widgets
from django.forms.models import ModelChoiceIterator from django.forms.models import ModelChoiceIterator
from django.utils.encoding import is_protected_type, smart_unicode from django.utils.encoding import is_protected_type, smart_unicode
...@@ -35,6 +36,7 @@ class Field(object): ...@@ -35,6 +36,7 @@ class Field(object):
empty = '' empty = ''
type_name = None type_name = None
_use_files = None _use_files = None
form_field_class = forms.CharField
def __init__(self, source=None): def __init__(self, source=None):
self.parent = None self.parent = None
...@@ -55,7 +57,7 @@ class Field(object): ...@@ -55,7 +57,7 @@ class Field(object):
self.root = parent.root or parent self.root = parent.root or parent
self.context = self.root.context self.context = self.root.context
if self.root.partial: if self.root.partial:
self.required = False self.required = False
def field_from_native(self, data, files, field_name, into): def field_from_native(self, data, files, field_name, into):
""" """
...@@ -223,7 +225,7 @@ class ModelField(WritableField): ...@@ -223,7 +225,7 @@ class ModelField(WritableField):
getattr(self.model_field, 'min_length', None)) getattr(self.model_field, 'min_length', None))
self.max_length = kwargs.pop('max_length', self.max_length = kwargs.pop('max_length',
getattr(self.model_field, 'max_length', None)) getattr(self.model_field, 'max_length', None))
super(ModelField, self).__init__(*args, **kwargs) super(ModelField, self).__init__(*args, **kwargs)
if self.min_length is not None: if self.min_length is not None:
...@@ -394,6 +396,7 @@ class PrimaryKeyRelatedField(RelatedField): ...@@ -394,6 +396,7 @@ class PrimaryKeyRelatedField(RelatedField):
Represents a to-one relationship as a pk value. Represents a to-one relationship as a pk value.
""" """
default_read_only = False default_read_only = False
form_field_class = forms.ChoiceField
# TODO: Remove these field hacks... # TODO: Remove these field hacks...
def prepare_value(self, obj): def prepare_value(self, obj):
...@@ -440,6 +443,7 @@ class ManyPrimaryKeyRelatedField(ManyRelatedField): ...@@ -440,6 +443,7 @@ class ManyPrimaryKeyRelatedField(ManyRelatedField):
Represents a to-many relationship as a pk value. Represents a to-many relationship as a pk value.
""" """
default_read_only = False default_read_only = False
form_field_class = forms.MultipleChoiceField
def prepare_value(self, obj): def prepare_value(self, obj):
return self.to_native(obj.pk) return self.to_native(obj.pk)
...@@ -483,6 +487,7 @@ class ManyPrimaryKeyRelatedField(ManyRelatedField): ...@@ -483,6 +487,7 @@ class ManyPrimaryKeyRelatedField(ManyRelatedField):
class SlugRelatedField(RelatedField): class SlugRelatedField(RelatedField):
default_read_only = False default_read_only = False
form_field_class = forms.ChoiceField
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.slug_field = kwargs.pop('slug_field', None) self.slug_field = kwargs.pop('slug_field', None)
...@@ -504,7 +509,7 @@ class SlugRelatedField(RelatedField): ...@@ -504,7 +509,7 @@ class SlugRelatedField(RelatedField):
class ManySlugRelatedField(ManyRelatedMixin, SlugRelatedField): class ManySlugRelatedField(ManyRelatedMixin, SlugRelatedField):
pass form_field_class = forms.MultipleChoiceField
### Hyperlinked relationships ### Hyperlinked relationships
...@@ -517,6 +522,7 @@ class HyperlinkedRelatedField(RelatedField): ...@@ -517,6 +522,7 @@ class HyperlinkedRelatedField(RelatedField):
slug_field = 'slug' slug_field = 'slug'
slug_url_kwarg = None # Defaults to same as `slug_field` unless overridden slug_url_kwarg = None # Defaults to same as `slug_field` unless overridden
default_read_only = False default_read_only = False
form_field_class = forms.ChoiceField
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
try: try:
...@@ -616,7 +622,7 @@ class ManyHyperlinkedRelatedField(ManyRelatedMixin, HyperlinkedRelatedField): ...@@ -616,7 +622,7 @@ class ManyHyperlinkedRelatedField(ManyRelatedMixin, HyperlinkedRelatedField):
""" """
Represents a to-many relationship, using hyperlinking. Represents a to-many relationship, using hyperlinking.
""" """
pass form_field_class = forms.MultipleChoiceField
class HyperlinkedIdentityField(Field): class HyperlinkedIdentityField(Field):
...@@ -674,6 +680,7 @@ class HyperlinkedIdentityField(Field): ...@@ -674,6 +680,7 @@ class HyperlinkedIdentityField(Field):
class BooleanField(WritableField): class BooleanField(WritableField):
type_name = 'BooleanField' type_name = 'BooleanField'
form_field_class = forms.BooleanField
widget = widgets.CheckboxInput widget = widgets.CheckboxInput
default_error_messages = { default_error_messages = {
'invalid': _(u"'%s' value must be either True or False."), 'invalid': _(u"'%s' value must be either True or False."),
...@@ -695,6 +702,7 @@ class BooleanField(WritableField): ...@@ -695,6 +702,7 @@ class BooleanField(WritableField):
class CharField(WritableField): class CharField(WritableField):
type_name = 'CharField' type_name = 'CharField'
form_field_class = forms.CharField
def __init__(self, max_length=None, min_length=None, *args, **kwargs): def __init__(self, max_length=None, min_length=None, *args, **kwargs):
self.max_length, self.min_length = max_length, min_length self.max_length, self.min_length = max_length, min_length
...@@ -739,6 +747,7 @@ class SlugField(CharField): ...@@ -739,6 +747,7 @@ class SlugField(CharField):
class ChoiceField(WritableField): class ChoiceField(WritableField):
type_name = 'ChoiceField' type_name = 'ChoiceField'
form_field_class = forms.ChoiceField
widget = widgets.Select widget = widgets.Select
default_error_messages = { default_error_messages = {
'invalid_choice': _('Select a valid choice. %(value)s is not one of the available choices.'), 'invalid_choice': _('Select a valid choice. %(value)s is not one of the available choices.'),
...@@ -785,6 +794,7 @@ class ChoiceField(WritableField): ...@@ -785,6 +794,7 @@ class ChoiceField(WritableField):
class EmailField(CharField): class EmailField(CharField):
type_name = 'EmailField' type_name = 'EmailField'
form_field_class = forms.EmailField
default_error_messages = { default_error_messages = {
'invalid': _('Enter a valid e-mail address.'), 'invalid': _('Enter a valid e-mail address.'),
...@@ -836,6 +846,7 @@ class RegexField(CharField): ...@@ -836,6 +846,7 @@ class RegexField(CharField):
class DateField(WritableField): class DateField(WritableField):
type_name = 'DateField' type_name = 'DateField'
widget = widgets.DateInput widget = widgets.DateInput
form_field_class = forms.DateField
default_error_messages = { default_error_messages = {
'invalid': _(u"'%s' value has an invalid date format. It must be " 'invalid': _(u"'%s' value has an invalid date format. It must be "
...@@ -874,6 +885,7 @@ class DateField(WritableField): ...@@ -874,6 +885,7 @@ class DateField(WritableField):
class DateTimeField(WritableField): class DateTimeField(WritableField):
type_name = 'DateTimeField' type_name = 'DateTimeField'
widget = widgets.DateTimeInput widget = widgets.DateTimeInput
form_field_class = forms.DateTimeField
default_error_messages = { default_error_messages = {
'invalid': _(u"'%s' value has an invalid format. It must be in " 'invalid': _(u"'%s' value has an invalid format. It must be in "
...@@ -928,6 +940,7 @@ class DateTimeField(WritableField): ...@@ -928,6 +940,7 @@ class DateTimeField(WritableField):
class IntegerField(WritableField): class IntegerField(WritableField):
type_name = 'IntegerField' type_name = 'IntegerField'
form_field_class = forms.IntegerField
default_error_messages = { default_error_messages = {
'invalid': _('Enter a whole number.'), 'invalid': _('Enter a whole number.'),
...@@ -957,6 +970,7 @@ class IntegerField(WritableField): ...@@ -957,6 +970,7 @@ class IntegerField(WritableField):
class FloatField(WritableField): class FloatField(WritableField):
type_name = 'FloatField' type_name = 'FloatField'
form_field_class = forms.FloatField
default_error_messages = { default_error_messages = {
'invalid': _("'%s' value must be a float."), 'invalid': _("'%s' value must be a float."),
...@@ -976,6 +990,7 @@ class FloatField(WritableField): ...@@ -976,6 +990,7 @@ class FloatField(WritableField):
class FileField(WritableField): class FileField(WritableField):
_use_files = True _use_files = True
type_name = 'FileField' type_name = 'FileField'
form_field_class = forms.FileField
widget = widgets.FileInput widget = widgets.FileInput
default_error_messages = { default_error_messages = {
...@@ -1018,6 +1033,7 @@ class FileField(WritableField): ...@@ -1018,6 +1033,7 @@ class FileField(WritableField):
class ImageField(FileField): class ImageField(FileField):
_use_files = True _use_files = True
form_field_class = forms.ImageField
default_error_messages = { default_error_messages = {
'invalid_image': _("Upload a valid image. The file you uploaded was either not an image or a corrupted image."), 'invalid_image': _("Upload a valid image. The file you uploaded was either not an image or a corrupted image."),
......
...@@ -306,26 +306,6 @@ class BrowsableAPIRenderer(BaseRenderer): ...@@ -306,26 +306,6 @@ class BrowsableAPIRenderer(BaseRenderer):
return True return True
def serializer_to_form_fields(self, serializer): def serializer_to_form_fields(self, serializer):
field_mapping = {
serializers.FloatField: forms.FloatField,
serializers.IntegerField: forms.IntegerField,
serializers.DateTimeField: forms.DateTimeField,
serializers.DateField: forms.DateField,
serializers.EmailField: forms.EmailField,
serializers.RegexField: forms.RegexField,
serializers.CharField: forms.CharField,
serializers.ChoiceField: forms.ChoiceField,
serializers.BooleanField: forms.BooleanField,
serializers.PrimaryKeyRelatedField: forms.ChoiceField,
serializers.ManyPrimaryKeyRelatedField: forms.MultipleChoiceField,
serializers.SlugRelatedField: forms.ChoiceField,
serializers.ManySlugRelatedField: forms.MultipleChoiceField,
serializers.HyperlinkedRelatedField: forms.ChoiceField,
serializers.ManyHyperlinkedRelatedField: forms.MultipleChoiceField,
serializers.FileField: forms.FileField,
serializers.ImageField: forms.ImageField,
}
fields = {} fields = {}
for k, v in serializer.get_fields().items(): for k, v in serializer.get_fields().items():
if getattr(v, 'read_only', True): if getattr(v, 'read_only', True):
...@@ -349,13 +329,7 @@ class BrowsableAPIRenderer(BaseRenderer): ...@@ -349,13 +329,7 @@ class BrowsableAPIRenderer(BaseRenderer):
kwargs['label'] = k kwargs['label'] = k
try: fields[k] = v.form_field_class(**kwargs)
fields[k] = field_mapping[v.__class__](**kwargs)
except KeyError:
if getattr(v, 'choices', None) is not None:
fields[k] = forms.ChoiceField(**kwargs)
else:
fields[k] = forms.CharField(**kwargs)
return fields return fields
def get_form(self, view, method, request): def get_form(self, view, method, request):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment