From 9ae0ca1caeb7d195719b9544da2a3a7c4fc85b26 Mon Sep 17 00:00:00 2001 From: "Michal Dvorak (cen38289)" Date: Mon, 3 Dec 2012 17:26:01 +0100 Subject: [PATCH 01/15] #467 Added label and help_text to Field --- rest_framework/fields.py | 23 +++++++++++++---------- rest_framework/serializers.py | 6 ++++++ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 482a3d485..907bab749 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -28,7 +28,7 @@ def is_simple_callable(obj): return ( (inspect.isfunction(obj) and not inspect.getargspec(obj)[0]) or (inspect.ismethod(obj) and len(inspect.getargspec(obj)[0]) <= 1) - ) + ) class Field(object): @@ -38,13 +38,15 @@ class Field(object): _use_files = None form_field_class = forms.CharField - def __init__(self, source=None): + def __init__(self, source=None, label=None, help_text=None): self.parent = None self.creation_counter = Field.creation_counter Field.creation_counter += 1 self.source = source + self.label = label + self.help_text = help_text def initialize(self, parent, field_name): """ @@ -123,11 +125,11 @@ class WritableField(Field): widget = widgets.TextInput default = None - def __init__(self, source=None, read_only=False, required=None, + def __init__(self, source=None, label=None, help_text=None, + read_only=False, required=None, validators=[], error_messages=None, widget=None, default=None, blank=None): - - super(WritableField, self).__init__(source=source) + super(WritableField, self).__init__(source=source, label=label, help_text=help_text) self.read_only = read_only if required is None: @@ -215,6 +217,7 @@ class ModelField(WritableField): """ A generic field that can be used against an arbitrary model field. """ + def __init__(self, *args, **kwargs): try: self.model_field = kwargs.pop('model_field') @@ -222,9 +225,9 @@ class ModelField(WritableField): raise ValueError("ModelField requires 'model_field' kwarg") self.min_length = kwargs.pop('min_length', - getattr(self.model_field, 'min_length', None)) + getattr(self.model_field, 'min_length', None)) 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) @@ -434,7 +437,7 @@ class PrimaryKeyRelatedField(RelatedField): # RelatedObject (reverse relationship) obj = getattr(obj, self.source or field_name) return self.to_native(obj.pk) - # Forward relationship + # Forward relationship return self.to_native(pk) @@ -469,7 +472,7 @@ class ManyPrimaryKeyRelatedField(ManyRelatedField): # RelatedManager (reverse relationship) queryset = getattr(obj, self.source or field_name) return [self.to_native(item.pk) for item in queryset.all()] - # Forward relationship + # Forward relationship return [self.to_native(item.pk) for item in queryset.all()] def from_native(self, data): @@ -913,7 +916,7 @@ class DateTimeField(WritableField): # call stack. warnings.warn(u"DateTimeField received a naive datetime (%s)" u" while time zone support is active." % value, - RuntimeWarning) + RuntimeWarning) default_timezone = timezone.get_default_timezone() value = timezone.make_aware(value, default_timezone) return value diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 4519ab053..2dab79149 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -428,6 +428,12 @@ class ModelSerializer(Serializer): if max_length: kwargs['max_length'] = max_length + if model_field.verbose_name: + kwargs['label'] = model_field.verbose_name + + if model_field.help_text: + kwargs['help_text'] = model_field.help_text + field_mapping = { models.FloatField: FloatField, models.IntegerField: IntegerField, From ad01fa0eae990ca1607d44cbabba5425c9d0b9a4 Mon Sep 17 00:00:00 2001 From: Michal Dvorak Date: Mon, 3 Dec 2012 19:07:07 +0100 Subject: [PATCH 02/15] #467 Added unit test --- rest_framework/serializers.py | 8 ++++---- rest_framework/tests/models.py | 3 ++- rest_framework/tests/serializer.py | 27 +++++++++++++++++++++++++-- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 2dab79149..e4fcbd670 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -428,11 +428,11 @@ class ModelSerializer(Serializer): if max_length: kwargs['max_length'] = max_length - if model_field.verbose_name: - kwargs['label'] = model_field.verbose_name + if model_field.verbose_name is not None: + kwargs['label'] = smart_unicode(model_field.verbose_name) - if model_field.help_text: - kwargs['help_text'] = model_field.help_text + if model_field.help_text is not None: + kwargs['help_text'] = smart_unicode(model_field.help_text) field_mapping = { models.FloatField: FloatField, diff --git a/rest_framework/tests/models.py b/rest_framework/tests/models.py index c35861c6c..a13f1ef34 100644 --- a/rest_framework/tests/models.py +++ b/rest_framework/tests/models.py @@ -1,6 +1,7 @@ from django.db import models from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.generic import GenericForeignKey, GenericRelation +from django.utils.translation import ugettext_lazy as _ # from django.contrib.auth.models import Group @@ -56,7 +57,7 @@ class Anchor(RESTFrameworkModel): class BasicModel(RESTFrameworkModel): - text = models.CharField(max_length=100) + text = models.CharField(max_length=100, verbose_name=_("Text"), help_text=_("Text description.")) class SlugBasedModel(RESTFrameworkModel): diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index 61a05da18..cc83a7402 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -1,6 +1,6 @@ import datetime from django.test import TestCase -from rest_framework import serializers +from rest_framework import serializers, fields from rest_framework.tests.models import (ActionItem, Anchor, BasicModel, BlankFieldModel, BlogPost, Book, CallableDefaultValueModel, DefaultValueModel, ManyToManyModel, Person, ReadOnlyManyToManyModel) @@ -48,7 +48,7 @@ class BookSerializer(serializers.ModelSerializer): class ActionItemSerializer(serializers.ModelSerializer): - + class Meta: model = ActionItem @@ -641,3 +641,26 @@ class BlankFieldTests(TestCase): """ serializer = self.not_blank_model_serializer_class(data=self.data) self.assertEquals(serializer.is_valid(), False) + + +# Test for issue #467 +class FieldLabelTest(TestCase): + def setUp(self): + class LabelModelSerializer(serializers.ModelSerializer): + # This is check that ctor supports both fields + additional = fields.CharField(label='Label', help_text='Help') + + class Meta: + model = BasicModel + + self.serializer_class = LabelModelSerializer + + def test_label_from_model(self): + """ + Validates that label and help_text are correctly copied from the model class. + """ + serializer = self.serializer_class() + text_field = serializer.fields['text'] + + self.assertEquals('Text', text_field.label) + self.assertEquals('Text description.', text_field.help_text) From dea0f9129c770b6a9ccebce7296235b529fa59e7 Mon Sep 17 00:00:00 2001 From: Michal Dvorak Date: Mon, 3 Dec 2012 19:10:57 +0100 Subject: [PATCH 03/15] Fixed screwed formatting --- rest_framework/fields.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 907bab749..74b4cb7c2 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -28,7 +28,7 @@ def is_simple_callable(obj): return ( (inspect.isfunction(obj) and not inspect.getargspec(obj)[0]) or (inspect.ismethod(obj) and len(inspect.getargspec(obj)[0]) <= 1) - ) + ) class Field(object): @@ -217,7 +217,6 @@ class ModelField(WritableField): """ A generic field that can be used against an arbitrary model field. """ - def __init__(self, *args, **kwargs): try: self.model_field = kwargs.pop('model_field') @@ -225,9 +224,9 @@ class ModelField(WritableField): raise ValueError("ModelField requires 'model_field' kwarg") self.min_length = kwargs.pop('min_length', - getattr(self.model_field, 'min_length', None)) + getattr(self.model_field, 'min_length', None)) 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) @@ -437,7 +436,7 @@ class PrimaryKeyRelatedField(RelatedField): # RelatedObject (reverse relationship) obj = getattr(obj, self.source or field_name) return self.to_native(obj.pk) - # Forward relationship + # Forward relationship return self.to_native(pk) @@ -472,7 +471,7 @@ class ManyPrimaryKeyRelatedField(ManyRelatedField): # RelatedManager (reverse relationship) queryset = getattr(obj, self.source or field_name) return [self.to_native(item.pk) for item in queryset.all()] - # Forward relationship + # Forward relationship return [self.to_native(item.pk) for item in queryset.all()] def from_native(self, data): @@ -916,7 +915,7 @@ class DateTimeField(WritableField): # call stack. warnings.warn(u"DateTimeField received a naive datetime (%s)" u" while time zone support is active." % value, - RuntimeWarning) + RuntimeWarning) default_timezone = timezone.get_default_timezone() value = timezone.make_aware(value, default_timezone) return value From a7849157bcfb8eb07b0ac934ae7c49a965bf6875 Mon Sep 17 00:00:00 2001 From: "Michal Dvorak (cen38289)" Date: Tue, 4 Dec 2012 10:00:14 +0100 Subject: [PATCH 04/15] Moved ctor test to separate unit test --- rest_framework/tests/serializer.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index cc83a7402..76c9c465a 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -647,9 +647,6 @@ class BlankFieldTests(TestCase): class FieldLabelTest(TestCase): def setUp(self): class LabelModelSerializer(serializers.ModelSerializer): - # This is check that ctor supports both fields - additional = fields.CharField(label='Label', help_text='Help') - class Meta: model = BasicModel @@ -664,3 +661,11 @@ class FieldLabelTest(TestCase): self.assertEquals('Text', text_field.label) self.assertEquals('Text description.', text_field.help_text) + + def test_field_ctor(self): + """ + This is check that ctor supports both label and help_text. + """ + fields.Field(label='Label', help_text='Help') + fields.CharField(label='Label', help_text='Help') + fields.ManyHyperlinkedRelatedField(view_name='fake', label='Label', help_text='Help') From 2a82b64963792b353a7a2634c003692bd4957c9f Mon Sep 17 00:00:00 2001 From: "Michal Dvorak (cen38289)" Date: Tue, 4 Dec 2012 14:16:45 +0100 Subject: [PATCH 05/15] Moved smart_unicode to Field ctor, to mimic Django Forms behavior. --- rest_framework/fields.py | 8 ++++++-- rest_framework/serializers.py | 4 ++-- rest_framework/tests/serializer.py | 10 +++++----- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 74b4cb7c2..f57dc57ff 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -45,8 +45,12 @@ class Field(object): Field.creation_counter += 1 self.source = source - self.label = label - self.help_text = help_text + + if label is not None: + self.label = smart_unicode(label) + + if help_text is not None: + self.help_text = smart_unicode(help_text) def initialize(self, parent, field_name): """ diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index e4fcbd670..37496be35 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -429,10 +429,10 @@ class ModelSerializer(Serializer): kwargs['max_length'] = max_length if model_field.verbose_name is not None: - kwargs['label'] = smart_unicode(model_field.verbose_name) + kwargs['label'] = model_field.verbose_name if model_field.help_text is not None: - kwargs['help_text'] = smart_unicode(model_field.help_text) + kwargs['help_text'] = model_field.help_text field_mapping = { models.FloatField: FloatField, diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index 76c9c465a..44adf92eb 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -659,13 +659,13 @@ class FieldLabelTest(TestCase): serializer = self.serializer_class() text_field = serializer.fields['text'] - self.assertEquals('Text', text_field.label) - self.assertEquals('Text description.', text_field.help_text) + self.assertEquals(u'Text', text_field.label) + self.assertEquals(u'Text description.', text_field.help_text) def test_field_ctor(self): """ This is check that ctor supports both label and help_text. """ - fields.Field(label='Label', help_text='Help') - fields.CharField(label='Label', help_text='Help') - fields.ManyHyperlinkedRelatedField(view_name='fake', label='Label', help_text='Help') + self.assertEquals(u'Label', fields.Field(label='Label', help_text='Help').label) + self.assertEquals(u'Help', fields.CharField(label='Label', help_text='Help').help_text) + self.assertEquals(u'Label', fields.ManyHyperlinkedRelatedField(view_name='fake', label='Label', help_text='Help').label) From 3691cd2ffd26ee639b88aa9f516f211e0558d454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20T=C3=B6rnqvist?= Date: Sat, 18 May 2013 13:26:59 +0300 Subject: [PATCH 06/15] Use smart_text() instead of nonexistant smart_unicode() --- rest_framework/fields.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 3c4e975ae..e4da14566 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -117,10 +117,10 @@ class Field(object): self.source = source if label is not None: - self.label = smart_unicode(label) + self.label = smart_text(label) if help_text is not None: - self.help_text = smart_unicode(help_text) + self.help_text = smart_text(help_text) def initialize(self, parent, field_name): """ From 764299843cbedce9afd07db7226f639208ff0608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20T=C3=B6rnqvist?= Date: Sat, 18 May 2013 13:30:39 +0300 Subject: [PATCH 07/15] ManyHyperlinkedRelatedField comes form rest_framework.relations now --- rest_framework/tests/serializer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index b0c7e5689..fc433a8f2 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals from django.utils.datastructures import MultiValueDict from django.test import TestCase -from rest_framework import serializers, fields +from rest_framework import serializers, fields, relations from rest_framework.tests.models import (HasPositiveIntegerAsChoice, Album, ActionItem, Anchor, BasicModel, BlankFieldModel, BlogPost, BlogPostComment, Book, CallableDefaultValueModel, DefaultValueModel, ManyToManyModel, Person, ReadOnlyManyToManyModel, Photo) @@ -1170,5 +1170,5 @@ class FieldLabelTest(TestCase): """ self.assertEquals(u'Label', fields.Field(label='Label', help_text='Help').label) self.assertEquals(u'Help', fields.CharField(label='Label', help_text='Help').help_text) - self.assertEquals(u'Label', fields.ManyHyperlinkedRelatedField(view_name='fake', label='Label', help_text='Help').label) + self.assertEquals(u'Label', relations.ManyHyperlinkedRelatedField(view_name='fake', label='Label', help_text='Help').label) From 1343398868937ed1e401054a8490bcea57d649d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20T=C3=B6rnqvist?= Date: Sat, 18 May 2013 15:15:02 +0300 Subject: [PATCH 08/15] Renderer uses form field's label and help, not attribute name --- rest_framework/renderers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index 8361cd409..a58025cd1 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -366,7 +366,8 @@ class BrowsableAPIRenderer(BaseRenderer): if getattr(v, 'default', None) is not None: kwargs['initial'] = v.default - kwargs['label'] = k + kwargs['label'] = v.label + kwargs['help_text'] = v.help_text fields[k] = v.form_field_class(**kwargs) From e7ddaf5472ba3746da2a0e9dfed6326fc90ce08e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20T=C3=B6rnqvist?= Date: Sat, 18 May 2013 16:50:59 +0300 Subject: [PATCH 09/15] Turns out label and help_text are not always there --- rest_framework/renderers.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index a58025cd1..2b56d6e41 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -366,8 +366,11 @@ class BrowsableAPIRenderer(BaseRenderer): if getattr(v, 'default', None) is not None: kwargs['initial'] = v.default - kwargs['label'] = v.label - kwargs['help_text'] = v.help_text + if getattr(v, 'label', None) is not None: + kwargs['label'] = v.label + + if getattr(v, 'help_text', None) is not None: + kwargs['help_text'] = v.help_text fields[k] = v.form_field_class(**kwargs) From e2d3aa65d78511b526ecac24bf4198dfa4f27c16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20T=C3=B6rnqvist?= Date: Sat, 18 May 2013 16:56:26 +0300 Subject: [PATCH 10/15] Move and rename LabelModelSerializer for further reuse --- rest_framework/tests/models.py | 7 +++++++ rest_framework/tests/serializer.py | 7 ++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/rest_framework/tests/models.py b/rest_framework/tests/models.py index 3465268b6..486ec7613 100644 --- a/rest_framework/tests/models.py +++ b/rest_framework/tests/models.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals from django.db import models from django.utils.translation import ugettext_lazy as _ +from rest_framework import serializers def foobar(): @@ -160,3 +161,9 @@ class NullableOneToOneSource(RESTFrameworkModel): name = models.CharField(max_length=100) target = models.OneToOneField(OneToOneTarget, null=True, blank=True, related_name='nullable_source') + +# Serializer used to test BasicModel +class BasicModelSerializer(serializers.ModelSerializer): + class Meta: + model = BasicModel + diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index fc433a8f2..343b958a8 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -5,6 +5,7 @@ from rest_framework import serializers, fields, relations from rest_framework.tests.models import (HasPositiveIntegerAsChoice, Album, ActionItem, Anchor, BasicModel, BlankFieldModel, BlogPost, BlogPostComment, Book, CallableDefaultValueModel, DefaultValueModel, ManyToManyModel, Person, ReadOnlyManyToManyModel, Photo) +from rest_framework.tests.models import BasicModelSerializer import datetime import pickle @@ -1148,11 +1149,7 @@ class DeserializeListTestCase(TestCase): # Test for issue #467 class FieldLabelTest(TestCase): def setUp(self): - class LabelModelSerializer(serializers.ModelSerializer): - class Meta: - model = BasicModel - - self.serializer_class = LabelModelSerializer + self.serializer_class = BasicModelSerializer def test_label_from_model(self): """ From e2a5ec035070755b4dc87dce65b46fa987138c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20T=C3=B6rnqvist?= Date: Sat, 18 May 2013 17:42:54 +0300 Subject: [PATCH 11/15] Change BasicModel.verbose_name Isn't it nicer to test for a text which is different from what the previous broken behavior was? Now we can really tell it works! --- rest_framework/tests/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/tests/models.py b/rest_framework/tests/models.py index 486ec7613..abf50a2de 100644 --- a/rest_framework/tests/models.py +++ b/rest_framework/tests/models.py @@ -34,7 +34,7 @@ class Anchor(RESTFrameworkModel): class BasicModel(RESTFrameworkModel): - text = models.CharField(max_length=100, verbose_name=_("Text"), help_text=_("Text description.")) + text = models.CharField(max_length=100, verbose_name=_("Text comes here"), help_text=_("Text description.")) class SlugBasedModel(RESTFrameworkModel): From e68ea16d7a8b94b2e975d3b4407059f02906bca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20T=C3=B6rnqvist?= Date: Sat, 18 May 2013 17:43:47 +0300 Subject: [PATCH 12/15] Update FieldLabelTest to use new BasicModel.verbose_name --- rest_framework/tests/serializer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index 343b958a8..59859ad7a 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -1158,7 +1158,7 @@ class FieldLabelTest(TestCase): serializer = self.serializer_class() text_field = serializer.fields['text'] - self.assertEquals(u'Text', text_field.label) + self.assertEquals(u'Text comes here', text_field.label) self.assertEquals(u'Text description.', text_field.help_text) def test_field_ctor(self): From 2795e842d60c4f1759129ab46bad6ba3e62195aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20T=C3=B6rnqvist?= Date: Sat, 18 May 2013 17:44:40 +0300 Subject: [PATCH 13/15] Two test cases for html rendering of API with labelized model --- rest_framework/tests/response.py | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/rest_framework/tests/response.py b/rest_framework/tests/response.py index aecf83f4e..d49aaa1f9 100644 --- a/rest_framework/tests/response.py +++ b/rest_framework/tests/response.py @@ -1,14 +1,18 @@ from __future__ import unicode_literals from django.test import TestCase +from rest_framework.tests.models import BasicModel, BasicModelSerializer from rest_framework.compat import patterns, url, include from rest_framework.response import Response from rest_framework.views import APIView +from rest_framework import generics +from rest_framework import routers from rest_framework import status from rest_framework.renderers import ( BaseRenderer, JSONRenderer, BrowsableAPIRenderer ) +from rest_framework import viewsets from rest_framework.settings import api_settings from rest_framework.compat import six @@ -65,11 +69,27 @@ class HTMLView1(APIView): return Response('text') +class HTMLNewModelViewSet(viewsets.ModelViewSet): + model = BasicModel + + +class HTMLNewModelView(generics.ListCreateAPIView): + renderer_classes = (BrowsableAPIRenderer,) + permission_classes = [] + serializer_class = BasicModelSerializer + model = BasicModel + + +new_model_viewset_router = routers.DefaultRouter() +new_model_viewset_router.register(r'', HTMLNewModelViewSet) + urlpatterns = patterns('', url(r'^.*\.(?P.+)$', MockView.as_view(renderer_classes=[RendererA, RendererB])), url(r'^$', MockView.as_view(renderer_classes=[RendererA, RendererB])), url(r'^html$', HTMLView.as_view()), url(r'^html1$', HTMLView1.as_view()), + url(r'^html_new_model$', HTMLNewModelView.as_view()), + url(r'^html_new_model_viewset', include(new_model_viewset_router.urls)), url(r'^restframework', include('rest_framework.urls', namespace='rest_framework')) ) @@ -173,3 +193,28 @@ class Issue122Tests(TestCase): Test if no infinite recursion occurs. """ self.client.get('/html1') + + +class Issue467Tests(TestCase): + """ + Tests for #467 + """ + + urls = 'rest_framework.tests.response' + + def test_viewset_label_help_text(self): + param = '?%s=%s' % ( + api_settings.URL_ACCEPT_OVERRIDE, + 'text/html' + ) + resp = self.client.get('/html_new_model_viewset/' + param) + self.assertEqual(resp['Content-Type'], 'text/html') + self.assertContains(resp, 'Text comes here') + self.assertContains(resp, 'Text description.') + + def test_form_has_label_and_help_text(self): + resp = self.client.get('/html_new_model') + self.assertEqual(resp['Content-Type'], 'text/html') + self.assertContains(resp, 'Text comes here') + self.assertContains(resp, 'Text description.') + From 1fd66fe8c6c97acbbfa5ca4725f3a770be4250fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20T=C3=B6rnqvist?= Date: Sat, 18 May 2013 18:27:36 +0300 Subject: [PATCH 14/15] Drop u'', it was used inconsistently and breaks for nothing with Python 3.2 --- rest_framework/tests/serializer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index 5685c0615..6a7deb491 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -1336,8 +1336,8 @@ class FieldLabelTest(TestCase): serializer = self.serializer_class() text_field = serializer.fields['text'] - self.assertEquals(u'Text comes here', text_field.label) - self.assertEquals(u'Text description.', text_field.help_text) + self.assertEquals('Text comes here', text_field.label) + self.assertEquals('Text description.', text_field.help_text) def test_field_ctor(self): """ From 99848b0321a07d7f05f2333f635756f45e058088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20T=C3=B6rnqvist?= Date: Sat, 18 May 2013 18:38:37 +0300 Subject: [PATCH 15/15] Drop another case of u'', this time from #530 code --- rest_framework/tests/serializer.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index 6a7deb491..8f901a85e 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -1343,9 +1343,9 @@ class FieldLabelTest(TestCase): """ This is check that ctor supports both label and help_text. """ - self.assertEquals(u'Label', fields.Field(label='Label', help_text='Help').label) - self.assertEquals(u'Help', fields.CharField(label='Label', help_text='Help').help_text) - self.assertEquals(u'Label', relations.ManyHyperlinkedRelatedField(view_name='fake', label='Label', help_text='Help').label) + self.assertEquals('Label', fields.Field(label='Label', help_text='Help').label) + self.assertEquals('Help', fields.CharField(label='Label', help_text='Help').help_text) + self.assertEquals('Label', relations.ManyHyperlinkedRelatedField(view_name='fake', label='Label', help_text='Help').label) class AttributeMappingOnAutogeneratedFieldsTests(TestCase):