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
This commit is contained in:
Marko Tibold 2012-11-29 01:10:32 +01:00
commit 968f4a5ca4
2 changed files with 21 additions and 31 deletions

View File

@ -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):
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
@ -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):
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):
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):
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):
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):
""" """
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):
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):
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):
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):
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):
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):
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):
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):
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):
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):
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."),

View File

@ -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):
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):