diff options
| author | Kyle | 2014-07-28 10:11:40 -0700 | 
|---|---|---|
| committer | Kyle | 2014-07-28 10:11:40 -0700 | 
| commit | e40ffd60d44d736d7e27ff454cba1905f0becc26 (patch) | |
| tree | fdededc77ff5a2720dcf96ca79ddfc9835106827 | |
| parent | 48b02f016a827bc254aba2aedb81b472189c2165 (diff) | |
| download | django-rest-framework-e40ffd60d44d736d7e27ff454cba1905f0becc26.tar.bz2 | |
Issue #1707 - Add documentation about the caching of `GenericAPIView.queryset`
to the `queryset` property, `get_queryset()`, and do generic-views.md; remove
changes to the viewsets.md documentation from my last commit.
| -rwxr-xr-x | docs/api-guide/generic-views.md | 8 | ||||
| -rw-r--r-- | docs/api-guide/viewsets.md | 15 | ||||
| -rw-r--r-- | rest_framework/generics.py | 8 | 
3 files changed, 15 insertions, 16 deletions
| diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md index 7d06f246..b76c18cf 100755 --- a/docs/api-guide/generic-views.md +++ b/docs/api-guide/generic-views.md @@ -43,6 +43,12 @@ For more complex cases you might also want to override various methods on the vi                  return 20              return 100 +        def list(self, request): +            # Note the use of `get_queryset()` instead of `self.queryset` +            queryset = self.get_queryset() +            serializer = UserSerializer(queryset, many=True) +            return Response(serializer.data) +  For very simple cases you might want to pass through any class attributes using the `.as_view()` method.  For example, your URLconf might include something the following entry.      url(r'^/users/', ListCreateAPIView.as_view(model=User), name='user-list') @@ -63,7 +69,7 @@ Each of the concrete generic views provided is built by combining `GenericAPIVie  The following attributes control the basic view behavior. -* `queryset` - The queryset that should be used for returning objects from this view.  Typically, you must either set this attribute, or override the `get_queryset()` method. +* `queryset` - The queryset that should be used for returning objects from this view.  Typically, you must either set this attribute, or override the `get_queryset()` method. If you are overriding a view method, it is important that you call `get_queryset()` instead of accessing this property directly, as `queryset` will get evaluated once, and those results will be cached for all subsequent requests.  * `serializer_class` - The serializer class that should be used for validating and deserializing input, and for serializing output.  Typically, you must either set this attribute, or override the `get_serializer_class()` method.  * `lookup_field` - The model field that should be used to for performing object lookup of individual model instances.  Defaults to `'pk'`.  Note that when using hyperlinked APIs you'll need to ensure that *both* the API views *and* the serializer classes set the lookup fields if you need to use a custom value.  * `lookup_url_kwarg` - The URL keyword argument that should be used for object lookup.  The URL conf should include a keyword argument corresponding to this value.  If unset this defaults to using the same value as `lookup_field`. diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md index 774e11b7..4f345abb 100644 --- a/docs/api-guide/viewsets.md +++ b/docs/api-guide/viewsets.md @@ -70,21 +70,6 @@ There are two main advantages of using a `ViewSet` class over using a `View` cla  Both of these come with a trade-off.  Using regular views and URL confs is more explicit and gives you more control.  ViewSets are helpful if you want to get up and running quickly, or when you have a large API and you want to enforce a consistent URL configuration throughout. -## Overriding ModelViewSet Methods - -Overriding the ModelViewSet is the same as overriding anything else, except you will need to remember to clone `self.queryset` before you use it, which you can do by using the built-in `get_queryset` method. For example: - -    class UserViewSet(viewsets.ModelViewSet): -        """ -        A viewset for viewing and editing user instances. -        """ -        queryset = User.objects.all() - -        def list(self, request): -            queryset = self.get_queryset() -            serializer = UserSerializer(queryset, many=True) -            return Response(serializer.data) -  ## Marking extra methods for routing  The default routers included with REST framework will provide routes for a standard set of create/retrieve/update/destroy style operations, as shown below: diff --git a/rest_framework/generics.py b/rest_framework/generics.py index 7bac510f..65ccd952 100644 --- a/rest_framework/generics.py +++ b/rest_framework/generics.py @@ -43,6 +43,10 @@ class GenericAPIView(views.APIView):      # You'll need to either set these attributes,      # or override `get_queryset()`/`get_serializer_class()`. +    # If you are overriding a view method, it is important that you call +    # `get_queryset()` instead of accessing the `queryset` property directly, +    # as `queryset` will get evaluated only once, and those results are cached +    # for all subsequent requests.      queryset = None      serializer_class = None @@ -256,6 +260,10 @@ class GenericAPIView(views.APIView):          This must be an iterable, and may be a queryset.          Defaults to using `self.queryset`. +        This method should always be used rather than accessing `self.queryset` +        directly, as `self.queryset` gets evaluated only once, and those results +        are cached for all subsequent requests. +          You may want to override this if you need to provide different          querysets depending on the incoming request. | 
