diff options
| author | Tom Christie | 2014-09-10 13:52:16 +0100 | 
|---|---|---|
| committer | Tom Christie | 2014-09-10 13:52:16 +0100 | 
| commit | 01c8c0cad977fc0787dbfc78bd34f4fd37e613f4 (patch) | |
| tree | 0bb60e5f7c419555d583e50d4fef8cb658d11ca1 /rest_framework | |
| parent | 234369aefdf08d7d0161d851866990754c00d31f (diff) | |
| download | django-rest-framework-01c8c0cad977fc0787dbfc78bd34f4fd37e613f4.tar.bz2 | |
Added help_text argument to fields
Diffstat (limited to 'rest_framework')
| -rw-r--r-- | rest_framework/compat.py | 23 | ||||
| -rw-r--r-- | rest_framework/fields.py | 5 | ||||
| -rw-r--r-- | rest_framework/serializers.py | 86 | 
3 files changed, 56 insertions, 58 deletions
| diff --git a/rest_framework/compat.py b/rest_framework/compat.py index fa0f0bfb..70b38df9 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -39,6 +39,17 @@ except ImportError:      django_filters = None +if django.VERSION >= (1, 6): +    def clean_manytomany_helptext(text): +        return text +else: +    # Up to version 1.5 many to many fields automatically suffix +    # the `help_text` attribute with hardcoded text. +    def clean_manytomany_helptext(text): +        if text.endswith(' Hold down "Control", or "Command" on a Mac, to select more than one.'): +            text = text[:-69] +        return text +  # Django-guardian is optional. Import only if guardian is in INSTALLED_APPS  # Fixes (#1712). We keep the try/except for the test suite.  guardian = None @@ -99,18 +110,8 @@ 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 e2bd5700..e71dce1d 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -101,7 +101,8 @@ class Field(object):      def __init__(self, read_only=False, write_only=False,                   required=None, default=empty, initial=None, source=None, -                 label=None, style=None, error_messages=None, validators=[]): +                 label=None, help_text=None, style=None, +                 error_messages=None, validators=[]):          self._creation_counter = Field._creation_counter          Field._creation_counter += 1 @@ -122,6 +123,7 @@ class Field(object):          self.source = source          self.initial = initial          self.label = label +        self.help_text = help_text          self.style = {} if style is None else style          self.validators = validators or self.default_validators[:] @@ -372,7 +374,6 @@ class IntegerField(Field):              self.validators.append(validators.MaxValueValidator(max_value))          if min_value is not None:              self.validators.append(validators.MinValueValidator(min_value)) -        print self.__class__.__name__, self.validators      def to_native(self, data):          try: diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 0727b8cd..459f8a8c 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -15,6 +15,7 @@ from django.core.exceptions import ValidationError  from django.db import models  from django.utils import six  from collections import namedtuple, OrderedDict +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  from rest_framework.utils import html, modelinfo, representation @@ -117,8 +118,9 @@ class SerializerMetaclass(type):      """      This metaclass sets a dictionary named `base_fields` on the class. -    Any fields included as attributes on either the class or it's superclasses -    will be include in the `base_fields` dictionary. +    Any instances of `Field` included as attributes on either the class +    or on any of its superclasses will be include in the +    `base_fields` dictionary.      """      @classmethod @@ -379,6 +381,10 @@ class ModelSerializer(Serializer):          info = modelinfo.get_field_info(self.opts.model)          ret = OrderedDict() +        serializer_url_field = self.get_url_field() +        if serializer_url_field: +            ret[api_settings.URL_FIELD_NAME] = serializer_url_field +          serializer_pk_field = self.get_pk_field(info.pk)          if serializer_pk_field:              ret[info.pk.name] = serializer_pk_field @@ -404,6 +410,9 @@ class ModelSerializer(Serializer):          return ret +    def get_url_field(self): +        return None +      def get_pk_field(self, model_field):          """          Returns a default instance of the pk field. @@ -446,13 +455,14 @@ class ModelSerializer(Serializer):          if model_field:              if model_field.null or model_field.blank:                  kwargs['required'] = False -            #  if model_field.help_text is not None: -            #      kwargs['help_text'] = model_field.help_text -            if model_field.verbose_name is not None: +            if model_field.verbose_name:                  kwargs['label'] = model_field.verbose_name              if not model_field.editable:                  kwargs['read_only'] = True                  kwargs.pop('queryset', None) +            help_text = clean_manytomany_helptext(model_field.help_text) +            if help_text: +                kwargs['help_text'] = help_text          return PrimaryKeyRelatedField(**kwargs) @@ -469,6 +479,9 @@ class ModelSerializer(Serializer):          if model_field.verbose_name is not None:              kwargs['label'] = model_field.verbose_name +        if model_field.help_text: +            kwargs['help_text'] = model_field.help_text +          if isinstance(model_field, models.AutoField) or not model_field.editable:              kwargs['read_only'] = True              # Read only implies that the field is not required. @@ -481,6 +494,14 @@ class ModelSerializer(Serializer):              # We have a cleaner repr on the instance if we don't set it.              kwargs.pop('required', None) +        if model_field.flatchoices: +            # If this model field contains choices, then use a ChoiceField, +            # rather than the standard serializer field for this type. +            # Note that we return this prior to setting any validation type +            # keyword arguments, as those are not valid initializers. +            kwargs['choices'] = model_field.flatchoices +            return ChoiceField(**kwargs) +          # Ensure that max_length is passed explicitly as a keyword arg,          # rather than as a validator.          max_length = getattr(model_field, 'max_length', None) @@ -561,23 +582,6 @@ class ModelSerializer(Serializer):          if validator_kwarg:              kwargs['validators'] = validator_kwarg -        # if issubclass(model_field.__class__, models.TextField): -        #     kwargs['widget'] = widgets.Textarea - -        # if model_field.help_text is not None: -        #     kwargs['help_text'] = model_field.help_text - -        # TODO: TypedChoiceField? -        if model_field.flatchoices:  # This ModelField contains choices -            kwargs['choices'] = model_field.flatchoices -            if model_field.null: -                kwargs['empty'] = None -            return ChoiceField(**kwargs) - -        if model_field.null and \ -                issubclass(model_field.__class__, (models.CharField, models.TextField)): -            kwargs['allow_none'] = True -          try:              return self.field_mapping[model_field.__class__](**kwargs)          except KeyError: @@ -597,33 +601,24 @@ class HyperlinkedModelSerializerOptions(ModelSerializerOptions):  class HyperlinkedModelSerializer(ModelSerializer):      _options_class = HyperlinkedModelSerializerOptions -    def get_default_fields(self): -        fields = super(HyperlinkedModelSerializer, self).get_default_fields() - -        if self.opts.view_name is None: -            self.opts.view_name = self.get_default_view_name(self.opts.model) - -        url_field_name = api_settings.URL_FIELD_NAME -        if url_field_name not in fields: -            ret = fields.__class__() -            ret[url_field_name] = self.get_url_field() -            ret.update(fields) -            fields = ret - -        return fields - -    def get_pk_field(self, model_field): -        if self.opts.fields and model_field.name in self.opts.fields: -            return self.get_field(model_field) -      def get_url_field(self): +        if self.opts.view_name is not None: +            view_name = self.opts.view_name +        else: +            view_name = self.get_default_view_name(self.opts.model) +          kwargs = { -            'view_name': self.get_default_view_name(self.opts.model) +            'view_name': view_name          }          if self.opts.lookup_field:              kwargs['lookup_field'] = self.opts.lookup_field +          return HyperlinkedIdentityField(**kwargs) +    def get_pk_field(self, model_field): +        if self.opts.fields and model_field.name in self.opts.fields: +            return self.get_field(model_field) +      def get_related_field(self, model_field, related_model, to_many, has_through_model):          """          Creates a default instance of a flat relational field. @@ -643,13 +638,14 @@ class HyperlinkedModelSerializer(ModelSerializer):          if model_field:              if model_field.null or model_field.blank:                  kwargs['required'] = False -            # if model_field.help_text is not None: -            #     kwargs['help_text'] = model_field.help_text -            if model_field.verbose_name is not None: +            if model_field.verbose_name:                  kwargs['label'] = model_field.verbose_name              if not model_field.editable:                  kwargs['read_only'] = True                  kwargs.pop('queryset', None) +            help_text = clean_manytomany_helptext(model_field.help_text) +            if help_text: +                kwargs['help_text'] = help_text          return HyperlinkedRelatedField(**kwargs) | 
