mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-10-31 07:57:55 +03:00 
			
		
		
		
	* Standardize spelling to American English (only in .md files) * Update remaining British english spell words to American english style * Configures the codespell pre-commit hook to enforce US English consistency changes: - Activates the `en-GB_to_en-US` built-in dictionary to flag British spellings - Created codespell-ignore-words.txt file to ignore specific words - include `code` and `names` for comprehensive typo checking in technical contexts. - changed the 'lets' to 'let's'.
		
			
				
	
	
		
			296 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			296 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """
 | |
| Generic views that provide commonly needed behavior.
 | |
| """
 | |
| from django.core.exceptions import ValidationError
 | |
| from django.db.models.query import QuerySet
 | |
| from django.http import Http404
 | |
| from django.shortcuts import get_object_or_404 as _get_object_or_404
 | |
| 
 | |
| from rest_framework import mixins, views
 | |
| from rest_framework.settings import api_settings
 | |
| 
 | |
| 
 | |
| def get_object_or_404(queryset, *filter_args, **filter_kwargs):
 | |
|     """
 | |
|     Same as Django's standard shortcut, but make sure to also raise 404
 | |
|     if the filter_kwargs don't match the required types.
 | |
|     """
 | |
|     try:
 | |
|         return _get_object_or_404(queryset, *filter_args, **filter_kwargs)
 | |
|     except (TypeError, ValueError, ValidationError):
 | |
|         raise Http404
 | |
| 
 | |
| 
 | |
| class GenericAPIView(views.APIView):
 | |
|     """
 | |
|     Base class for all other generic views.
 | |
|     """
 | |
|     # 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
 | |
| 
 | |
|     # If you want to use object lookups other than pk, set 'lookup_field'.
 | |
|     # For more complex lookup requirements override `get_object()`.
 | |
|     lookup_field = 'pk'
 | |
|     lookup_url_kwarg = None
 | |
| 
 | |
|     # The filter backend classes to use for queryset filtering
 | |
|     filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
 | |
| 
 | |
|     # The style to use for queryset pagination.
 | |
|     pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
 | |
| 
 | |
|     # Allow generic typing checking for generic views.
 | |
|     def __class_getitem__(cls, *args, **kwargs):
 | |
|         return cls
 | |
| 
 | |
|     def get_queryset(self):
 | |
|         """
 | |
|         Get the list of items for this view.
 | |
|         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.
 | |
| 
 | |
|         (Eg. return a list of items that is specific to the user)
 | |
|         """
 | |
|         assert self.queryset is not None, (
 | |
|             "'%s' should either include a `queryset` attribute, "
 | |
|             "or override the `get_queryset()` method."
 | |
|             % self.__class__.__name__
 | |
|         )
 | |
| 
 | |
|         queryset = self.queryset
 | |
|         if isinstance(queryset, QuerySet):
 | |
|             # Ensure queryset is re-evaluated on each request.
 | |
|             queryset = queryset.all()
 | |
|         return queryset
 | |
| 
 | |
|     def get_object(self):
 | |
|         """
 | |
|         Returns the object the view is displaying.
 | |
| 
 | |
|         You may want to override this if you need to provide non-standard
 | |
|         queryset lookups.  Eg if objects are referenced using multiple
 | |
|         keyword arguments in the url conf.
 | |
|         """
 | |
|         queryset = self.filter_queryset(self.get_queryset())
 | |
| 
 | |
|         # Perform the lookup filtering.
 | |
|         lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
 | |
| 
 | |
|         assert lookup_url_kwarg in self.kwargs, (
 | |
|             'Expected view %s to be called with a URL keyword argument '
 | |
|             'named "%s". Fix your URL conf, or set the `.lookup_field` '
 | |
|             'attribute on the view correctly.' %
 | |
|             (self.__class__.__name__, lookup_url_kwarg)
 | |
|         )
 | |
| 
 | |
|         filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
 | |
|         obj = get_object_or_404(queryset, **filter_kwargs)
 | |
| 
 | |
|         # May raise a permission denied
 | |
|         self.check_object_permissions(self.request, obj)
 | |
| 
 | |
|         return obj
 | |
| 
 | |
|     def get_serializer(self, *args, **kwargs):
 | |
|         """
 | |
|         Return the serializer instance that should be used for validating and
 | |
|         deserializing input, and for serializing output.
 | |
|         """
 | |
|         serializer_class = self.get_serializer_class()
 | |
|         kwargs.setdefault('context', self.get_serializer_context())
 | |
|         return serializer_class(*args, **kwargs)
 | |
| 
 | |
|     def get_serializer_class(self):
 | |
|         """
 | |
|         Return the class to use for the serializer.
 | |
|         Defaults to using `self.serializer_class`.
 | |
| 
 | |
|         You may want to override this if you need to provide different
 | |
|         serializations depending on the incoming request.
 | |
| 
 | |
|         (Eg. admins get full serialization, others get basic serialization)
 | |
|         """
 | |
|         assert self.serializer_class is not None, (
 | |
|             "'%s' should either include a `serializer_class` attribute, "
 | |
|             "or override the `get_serializer_class()` method."
 | |
|             % self.__class__.__name__
 | |
|         )
 | |
| 
 | |
|         return self.serializer_class
 | |
| 
 | |
|     def get_serializer_context(self):
 | |
|         """
 | |
|         Extra context provided to the serializer class.
 | |
|         """
 | |
|         return {
 | |
|             'request': self.request,
 | |
|             'format': self.format_kwarg,
 | |
|             'view': self
 | |
|         }
 | |
| 
 | |
|     def filter_queryset(self, queryset):
 | |
|         """
 | |
|         Given a queryset, filter it with whichever filter backend is in use.
 | |
| 
 | |
|         You are unlikely to want to override this method, although you may need
 | |
|         to call it either from a list view, or from a custom `get_object`
 | |
|         method if you want to apply the configured filtering backend to the
 | |
|         default queryset.
 | |
|         """
 | |
|         for backend in list(self.filter_backends):
 | |
|             queryset = backend().filter_queryset(self.request, queryset, self)
 | |
|         return queryset
 | |
| 
 | |
|     @property
 | |
|     def paginator(self):
 | |
|         """
 | |
|         The paginator instance associated with the view, or `None`.
 | |
|         """
 | |
|         if not hasattr(self, '_paginator'):
 | |
|             if self.pagination_class is None:
 | |
|                 self._paginator = None
 | |
|             else:
 | |
|                 self._paginator = self.pagination_class()
 | |
|         return self._paginator
 | |
| 
 | |
|     def paginate_queryset(self, queryset):
 | |
|         """
 | |
|         Return a single page of results, or `None` if pagination is disabled.
 | |
|         """
 | |
|         if self.paginator is None:
 | |
|             return None
 | |
|         return self.paginator.paginate_queryset(queryset, self.request, view=self)
 | |
| 
 | |
|     def get_paginated_response(self, data):
 | |
|         """
 | |
|         Return a paginated style `Response` object for the given output data.
 | |
|         """
 | |
|         assert self.paginator is not None
 | |
|         return self.paginator.get_paginated_response(data)
 | |
| 
 | |
| 
 | |
| # Concrete view classes that provide method handlers
 | |
| # by composing the mixin classes with the base view.
 | |
| 
 | |
| class CreateAPIView(mixins.CreateModelMixin,
 | |
|                     GenericAPIView):
 | |
|     """
 | |
|     Concrete view for creating a model instance.
 | |
|     """
 | |
|     def post(self, request, *args, **kwargs):
 | |
|         return self.create(request, *args, **kwargs)
 | |
| 
 | |
| 
 | |
| class ListAPIView(mixins.ListModelMixin,
 | |
|                   GenericAPIView):
 | |
|     """
 | |
|     Concrete view for listing a queryset.
 | |
|     """
 | |
|     def get(self, request, *args, **kwargs):
 | |
|         return self.list(request, *args, **kwargs)
 | |
| 
 | |
| 
 | |
| class RetrieveAPIView(mixins.RetrieveModelMixin,
 | |
|                       GenericAPIView):
 | |
|     """
 | |
|     Concrete view for retrieving a model instance.
 | |
|     """
 | |
|     def get(self, request, *args, **kwargs):
 | |
|         return self.retrieve(request, *args, **kwargs)
 | |
| 
 | |
| 
 | |
| class DestroyAPIView(mixins.DestroyModelMixin,
 | |
|                      GenericAPIView):
 | |
|     """
 | |
|     Concrete view for deleting a model instance.
 | |
|     """
 | |
|     def delete(self, request, *args, **kwargs):
 | |
|         return self.destroy(request, *args, **kwargs)
 | |
| 
 | |
| 
 | |
| class UpdateAPIView(mixins.UpdateModelMixin,
 | |
|                     GenericAPIView):
 | |
|     """
 | |
|     Concrete view for updating a model instance.
 | |
|     """
 | |
|     def put(self, request, *args, **kwargs):
 | |
|         return self.update(request, *args, **kwargs)
 | |
| 
 | |
|     def patch(self, request, *args, **kwargs):
 | |
|         return self.partial_update(request, *args, **kwargs)
 | |
| 
 | |
| 
 | |
| class ListCreateAPIView(mixins.ListModelMixin,
 | |
|                         mixins.CreateModelMixin,
 | |
|                         GenericAPIView):
 | |
|     """
 | |
|     Concrete view for listing a queryset or creating a model instance.
 | |
|     """
 | |
|     def get(self, request, *args, **kwargs):
 | |
|         return self.list(request, *args, **kwargs)
 | |
| 
 | |
|     def post(self, request, *args, **kwargs):
 | |
|         return self.create(request, *args, **kwargs)
 | |
| 
 | |
| 
 | |
| class RetrieveUpdateAPIView(mixins.RetrieveModelMixin,
 | |
|                             mixins.UpdateModelMixin,
 | |
|                             GenericAPIView):
 | |
|     """
 | |
|     Concrete view for retrieving, updating a model instance.
 | |
|     """
 | |
|     def get(self, request, *args, **kwargs):
 | |
|         return self.retrieve(request, *args, **kwargs)
 | |
| 
 | |
|     def put(self, request, *args, **kwargs):
 | |
|         return self.update(request, *args, **kwargs)
 | |
| 
 | |
|     def patch(self, request, *args, **kwargs):
 | |
|         return self.partial_update(request, *args, **kwargs)
 | |
| 
 | |
| 
 | |
| class RetrieveDestroyAPIView(mixins.RetrieveModelMixin,
 | |
|                              mixins.DestroyModelMixin,
 | |
|                              GenericAPIView):
 | |
|     """
 | |
|     Concrete view for retrieving or deleting a model instance.
 | |
|     """
 | |
|     def get(self, request, *args, **kwargs):
 | |
|         return self.retrieve(request, *args, **kwargs)
 | |
| 
 | |
|     def delete(self, request, *args, **kwargs):
 | |
|         return self.destroy(request, *args, **kwargs)
 | |
| 
 | |
| 
 | |
| class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
 | |
|                                    mixins.UpdateModelMixin,
 | |
|                                    mixins.DestroyModelMixin,
 | |
|                                    GenericAPIView):
 | |
|     """
 | |
|     Concrete view for retrieving, updating or deleting a model instance.
 | |
|     """
 | |
|     def get(self, request, *args, **kwargs):
 | |
|         return self.retrieve(request, *args, **kwargs)
 | |
| 
 | |
|     def put(self, request, *args, **kwargs):
 | |
|         return self.update(request, *args, **kwargs)
 | |
| 
 | |
|     def patch(self, request, *args, **kwargs):
 | |
|         return self.partial_update(request, *args, **kwargs)
 | |
| 
 | |
|     def delete(self, request, *args, **kwargs):
 | |
|         return self.destroy(request, *args, **kwargs)
 |