Skip to content

Instantly share code, notes, and snippets.

@guglielmo
Created January 29, 2013 18:48
Show Gist options
  • Save guglielmo/4666559 to your computer and use it in GitHub Desktop.
Save guglielmo/4666559 to your computer and use it in GitHub Desktop.
This code is related to the django rest framework project (https://github.com/tomchristie/django-rest-framework). It's an implementation of the suggestion of Alan Plum in this google groups discussion (https://groups.google.com/forum/?fromgroups=#!topic/django-rest-framework/XRHdi8ddXiw) to have different representations of list and detail views…
from django.http import Http404
from rest_framework.mixins import ListModelMixin
from rest_framework.response import Response
class ShortListModelMixin(ListModelMixin):
"""
Extends ListModelMixin,
allowing the specification of the list_fields arguments for the .list() method
different fields can be shown for list and detail views
"""
def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
self.object_list = self.filter_queryset(queryset)
# Default is to allow empty querysets. This can be altered by setting
# `.allow_empty = False`, to raise 404 errors on empty querysets.
allow_empty = self.get_allow_empty()
if not allow_empty and not self.object_list:
class_name = self.__class__.__name__
error_msg = self.empty_error % {'class_name': class_name}
raise Http404(error_msg)
# Pagination size is set by the `.paginate_by` attribute,
# which may be `None` to disable pagination.
page_size = self.get_paginate_by(self.object_list)
if page_size:
packed = self.paginate_queryset(self.object_list, page_size)
paginator, page, queryset, is_paginated = packed
serializer = self.get_pagination_serializer(page)
else:
serializer = self.get_serializer(self.object_list)
if 'list_fields' in kwargs and len(kwargs['list_fields']):
serializer.data['results'] = [dict((k,v) for k, v in i.iteritems() if k in kwargs['list_fields']) for i in serializer.data['results']]
return Response(serializer.data)
class SnippetList(ShortListModelMixin, generics.ListCreateAPIView):
"""
List of available snippets
"""
model = Snippet
serializer_class = SnippetSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly, )
list_fields = ('url', 'title', 'owner', 'highlight')
def get(self, request, *args, **kwargs):
return self.list(request, *args, list_fields=self.list_fields, **kwargs)
def pre_save(self, obj):
obj.owner = self.request.user
@stevekane
Copy link

Your implementation seems sound enough but I don't really understand the approach you are taking with respect to your list_fields attribute.

I would probably write your code a little differently and just define your mixin like this:

class ShortListModelMixin(ListModelMixin):
  """
  Extends ListModelMixin,
  allowing the specification of the list_fields arguments for the .list() method
  different fields can be shown for list and detail views
  """

  def list(self, request, *args, **kwargs):
    #Use your attribute self.list_fields here rather than pass it in as a kwarg
    # Mixin code here ....

class SnippetList(ShortListModelMixin, generics.ListCreateAPIView):
    #no need to define any methods here unless desired
    #just define list_fields and any other normal attributes you may desire

@speg
Copy link

speg commented Jun 12, 2013

On line 35 I get a can't set property error. I ended doing the same thing, but in the Serializer class. I then override the data property and rebuild the dict based on a list_fields parameter which I'm now passing to the Serializer.

@IlianIliev
Copy link

How about this approach -> https://gist.github.com/IlianIliev/6462502

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment