mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-08 06:14:47 +03:00
Modified the get_context method of the AdminRenderer to add urls to data from ModelSerializer.
This commit is contained in:
parent
af5474f9b3
commit
1bcb2bd088
|
@ -25,10 +25,13 @@ from rest_framework.compat import (
|
||||||
)
|
)
|
||||||
from rest_framework.exceptions import ParseError
|
from rest_framework.exceptions import ParseError
|
||||||
from rest_framework.request import is_form_media_type, override_method
|
from rest_framework.request import is_form_media_type, override_method
|
||||||
|
from rest_framework.reverse import reverse
|
||||||
from rest_framework.settings import api_settings
|
from rest_framework.settings import api_settings
|
||||||
from rest_framework.utils import encoders
|
from rest_framework.utils import encoders, model_meta
|
||||||
from rest_framework.utils.breadcrumbs import get_breadcrumbs
|
from rest_framework.utils.breadcrumbs import get_breadcrumbs
|
||||||
from rest_framework.utils.field_mapping import ClassLookupDict
|
from rest_framework.utils.field_mapping import (
|
||||||
|
ClassLookupDict, get_detail_view_name
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def zero_as_none(value):
|
def zero_as_none(value):
|
||||||
|
@ -730,10 +733,13 @@ class AdminRenderer(BrowsableAPIRenderer):
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def get_context(self, data, accepted_media_type, renderer_context):
|
def get_context(self, data, accepted_media_type, renderer_context, reverse_func=None):
|
||||||
"""
|
"""
|
||||||
Render the HTML for the browsable API representation.
|
Render the HTML for the browsable API representation.
|
||||||
"""
|
"""
|
||||||
|
if not reverse_func:
|
||||||
|
reverse_func = reverse
|
||||||
|
|
||||||
context = super(AdminRenderer, self).get_context(
|
context = super(AdminRenderer, self).get_context(
|
||||||
data, accepted_media_type, renderer_context
|
data, accepted_media_type, renderer_context
|
||||||
)
|
)
|
||||||
|
@ -757,6 +763,31 @@ class AdminRenderer(BrowsableAPIRenderer):
|
||||||
header = results
|
header = results
|
||||||
style = 'detail'
|
style = 'detail'
|
||||||
|
|
||||||
|
if style == 'list' and results:
|
||||||
|
serializer_class = getattr(context['view'], 'serializer_class', None)
|
||||||
|
fields = getattr(serializer_class.Meta, 'fields', None)
|
||||||
|
|
||||||
|
if issubclass(serializer_class, serializers.ModelSerializer) and fields \
|
||||||
|
and 'url' not in fields:
|
||||||
|
request = context['request']
|
||||||
|
|
||||||
|
def add_url(item):
|
||||||
|
info = model_meta.get_field_info(serializer_class.Meta.model)
|
||||||
|
pk = None
|
||||||
|
|
||||||
|
for field_name, field in info.fields_and_pk.items():
|
||||||
|
if field.primary_key and (field_name in item):
|
||||||
|
pk = item[field_name]
|
||||||
|
|
||||||
|
if pk:
|
||||||
|
view_name = get_detail_view_name(serializer_class.Meta.model)
|
||||||
|
url = reverse_func(view_name, kwargs={'pk': pk}, request=request)
|
||||||
|
item['url'] = url
|
||||||
|
|
||||||
|
return item
|
||||||
|
|
||||||
|
results = [add_url(result) for result in results]
|
||||||
|
|
||||||
columns = [key for key in header.keys() if key != 'url']
|
columns = [key for key in header.keys() if key != 'url']
|
||||||
details = [key for key in header.keys() if key != 'url']
|
details = [key for key in header.keys() if key != 'url']
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,14 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from rest_framework import permissions, serializers, status
|
from rest_framework import permissions, serializers, status
|
||||||
from rest_framework.renderers import (
|
from rest_framework.renderers import (
|
||||||
BaseRenderer, BrowsableAPIRenderer, HTMLFormRenderer, JSONRenderer
|
AdminRenderer, BaseRenderer, BrowsableAPIRenderer, HTMLFormRenderer,
|
||||||
|
JSONRenderer
|
||||||
)
|
)
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.settings import api_settings
|
from rest_framework.settings import api_settings
|
||||||
from rest_framework.test import APIRequestFactory
|
from rest_framework.test import APIRequestFactory
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
|
from tests.utils import mock_reverse
|
||||||
|
|
||||||
DUMMYSTATUS = status.HTTP_200_OK
|
DUMMYSTATUS = status.HTTP_200_OK
|
||||||
DUMMYCONTENT = 'dummycontent'
|
DUMMYCONTENT = 'dummycontent'
|
||||||
|
@ -42,6 +44,12 @@ class DummyTestModel(models.Model):
|
||||||
name = models.CharField(max_length=42, default='')
|
name = models.CharField(max_length=42, default='')
|
||||||
|
|
||||||
|
|
||||||
|
class DummySerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = DummyTestModel
|
||||||
|
fields = ('pk', 'name',)
|
||||||
|
|
||||||
|
|
||||||
class BasicRendererTests(TestCase):
|
class BasicRendererTests(TestCase):
|
||||||
def test_expected_results(self):
|
def test_expected_results(self):
|
||||||
for value, renderer_cls, expected in expected_results:
|
for value, renderer_cls, expected in expected_results:
|
||||||
|
@ -103,6 +111,12 @@ class HTMLView1(APIView):
|
||||||
def get(self, request, **kwargs):
|
def get(self, request, **kwargs):
|
||||||
return Response('text')
|
return Response('text')
|
||||||
|
|
||||||
|
|
||||||
|
class AdminRendererView(APIView):
|
||||||
|
renderer_classes = (AdminRenderer, JSONRenderer)
|
||||||
|
serializer_class = DummySerializer
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^.*\.(?P<format>.+)$', MockView.as_view(renderer_classes=[RendererA, RendererB])),
|
url(r'^.*\.(?P<format>.+)$', MockView.as_view(renderer_classes=[RendererA, RendererB])),
|
||||||
url(r'^$', MockView.as_view(renderer_classes=[RendererA, RendererB])),
|
url(r'^$', MockView.as_view(renderer_classes=[RendererA, RendererB])),
|
||||||
|
@ -111,6 +125,7 @@ urlpatterns = [
|
||||||
url(r'^html$', HTMLView.as_view()),
|
url(r'^html$', HTMLView.as_view()),
|
||||||
url(r'^html1$', HTMLView1.as_view()),
|
url(r'^html1$', HTMLView1.as_view()),
|
||||||
url(r'^empty$', EmptyGETView.as_view()),
|
url(r'^empty$', EmptyGETView.as_view()),
|
||||||
|
url(r'^admin_renderer$', AdminRendererView.as_view()),
|
||||||
url(r'^api', include('rest_framework.urls', namespace='rest_framework'))
|
url(r'^api', include('rest_framework.urls', namespace='rest_framework'))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -459,3 +474,19 @@ class TestHiddenFieldHTMLFormRenderer(TestCase):
|
||||||
field = serializer['published']
|
field = serializer['published']
|
||||||
rendered = renderer.render_field(field, {})
|
rendered = renderer.render_field(field, {})
|
||||||
assert rendered == ''
|
assert rendered == ''
|
||||||
|
|
||||||
|
|
||||||
|
class TestAdminRenderer(TestCase):
|
||||||
|
def test_admin_renderer_adds_url(self):
|
||||||
|
"""AdminRenderer should add a URL to the results if they come from a ModelSerializer"""
|
||||||
|
renderer = AdminRenderer()
|
||||||
|
data = [OrderedDict([('pk', 1), ('name', 'dummyname')])]
|
||||||
|
view = AdminRendererView()
|
||||||
|
request = view.initialize_request(APIRequestFactory().request())
|
||||||
|
context = {'view': view, 'request': request,
|
||||||
|
'response': view.as_view()(request)}
|
||||||
|
|
||||||
|
rendered_context = renderer.get_context(data, 'text/html', context, reverse_func=mock_reverse)
|
||||||
|
|
||||||
|
results = rendered_context['results'][0]
|
||||||
|
assert results['url'] == 'http://example.org/dummytestmodel-detail/1/'
|
||||||
|
|
Loading…
Reference in New Issue
Block a user