Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you access data in the template when using DRF ModelViewSet and TemplateHTMLRenderer?

I've got a Django Rest Framework ModelViewSet and am trying to use the TemplateHTMLRenderer to display HTML. Following along in the tutorial:

from rest_framework import permissions, renderers, viewsets
from rest_framework.decorators import link

from . import models, serializers
from .permissions import IsOwnerOrReadOnly


class SnippetViewSet(viewsets.ModelViewSet):
    template_name = 'snippet-list.html'
    queryset = models.Snippet.objects.all()
    serializer_class = serializers.SnippetSerializer
    renderer_classes = (renderers.TemplateHTMLRenderer,)
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                          IsOwnerOrReadOnly,)

    @link(renderer_classes=[renderers.StaticHTMLRenderer])
    def highlight(self, request, *args, **kwargs):
        snippet = self.get_object()
        return Response(snippet.highlighted)

    def pre_save(self, obj):
        obj.owner = self.request.user

If I add a key in def resolve_context() I can access the model objects in my template that are passed into the RequestContext. If I don't add the data key then I don't know how to access the Snippets.

def resolve_context(self, data, request, response):
    if response.exception:
        data['status_code'] = response.status_code

    #return RequestContext(request, data)  # original source on github
    return RequestContext(request, {'data': data})  # if I add a key I can access it

So I've got to be missing something easy or how I'm expecting this to behave is not how the authors intended?

like image 456
Scott Woodall Avatar asked Sep 20 '13 20:09

Scott Woodall


1 Answers

I would go this way:

class SnippetViewSet(viewsets.ModelViewSet):
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
    renderer_classes = (renderers.JSONRenderer, renderers.TemplateHTMLRenderer)

    def list(self, request, *args, **kwargs):
        response = super(SnippetViewSet, self).list(request, *args, **kwargs)
        if request.accepted_renderer.format == 'html':
            return Response({'data': response.data}, template_name='home.html')
        return response

and use http://127.0.0.1:8000/snippets/.html to get table (or whatever suffix you use).

This way you don't override resolver for each render type.

Other solution would be to just create dedicated view for list action and only use HTML renderer. But then you would have a small code duplication.

like image 50
mariodev Avatar answered Nov 04 '22 16:11

mariodev