mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-10-31 07:57:55 +03:00 
			
		
		
		
	Include import paths throughout docs.
Closes #1051. Thanks to @pydanny for the report.
This commit is contained in:
		
							parent
							
								
									f84d4951bf
								
							
						
					
					
						commit
						5e40e50f2b
					
				|  | @ -46,6 +46,11 @@ The default authentication schemes may be set globally, using the `DEFAULT_AUTHE | |||
| You can also set the authentication scheme on a per-view or per-viewset basis, | ||||
| using the `APIView` class based views. | ||||
| 
 | ||||
|     from rest_framework.authentication import SessionAuthentication, BasicAuthentication | ||||
|     from rest_framework.permissions import IsAuthenticated | ||||
|     from rest_framework.response import Response | ||||
|     from rest_framework.views import APIView | ||||
| 
 | ||||
|     class ExampleView(APIView): | ||||
|         authentication_classes = (SessionAuthentication, BasicAuthentication) | ||||
|         permission_classes = (IsAuthenticated,) | ||||
|  | @ -157,11 +162,16 @@ The `curl` command line tool may be useful for testing token authenticated APIs. | |||
| 
 | ||||
| If you want every user to have an automatically generated Token, you can simply catch the User's `post_save` signal. | ||||
| 
 | ||||
|     from django.dispatch import receiver | ||||
|     from rest_framework.authtoken.models import Token | ||||
| 
 | ||||
|     @receiver(post_save, sender=User) | ||||
|     def create_auth_token(sender, instance=None, created=False, **kwargs): | ||||
|         if created: | ||||
|             Token.objects.create(user=instance) | ||||
| 
 | ||||
| Note that you'll want to ensure you place this code snippet in an installed `models.py` module, or some other location that will be imported by Django on startup. | ||||
| 
 | ||||
| If you've already created some users, you can generate tokens for all existing users like this: | ||||
| 
 | ||||
|     from django.contrib.auth.models import User | ||||
|  | @ -336,6 +346,10 @@ If the `.authenticate_header()` method is not overridden, the authentication sch | |||
| 
 | ||||
| The following example will authenticate any incoming request as the user given by the username in a custom request header named 'X_USERNAME'. | ||||
| 
 | ||||
| 	from django.contrib.auth.models import User | ||||
|     from rest_framework import authentication | ||||
|     from rest_framework import exceptions | ||||
| 
 | ||||
|     class ExampleAuthentication(authentication.BaseAuthentication): | ||||
|         def authenticate(self, request): | ||||
|             username = request.META.get('X_USERNAME') | ||||
|  |  | |||
|  | @ -54,6 +54,8 @@ The `select_renderer()` method should return a two-tuple of (renderer instance, | |||
| The following is a custom content negotiation class which ignores the client | ||||
| request when selecting the appropriate parser or renderer. | ||||
| 
 | ||||
|     from rest_framework.negotiation import BaseContentNegotiation | ||||
| 
 | ||||
|     class IgnoreClientContentNegotiation(BaseContentNegotiation): | ||||
|         def select_parser(self, request, parsers): | ||||
|             """ | ||||
|  | @ -77,6 +79,10 @@ The default content negotiation class may be set globally, using the `DEFAULT_CO | |||
| 
 | ||||
| You can also set the content negotiation used for an individual view, or viewset, using the `APIView` class based views. | ||||
| 
 | ||||
| 	from myapp.negotiation import IgnoreClientContentNegotiation | ||||
|     from rest_framework.response import Response | ||||
|     from rest_framework.views import APIView | ||||
| 
 | ||||
|     class NoNegotiationView(APIView): | ||||
|         """ | ||||
|         An example view that does not perform content negotiation. | ||||
|  |  | |||
|  | @ -78,6 +78,9 @@ A generic, **read-only** field.  You can use this field for any attribute that d | |||
| 
 | ||||
| For example, using the following model. | ||||
| 
 | ||||
|     from django.db import models | ||||
|     from django.utils.timezone import now | ||||
| 
 | ||||
|     class Account(models.Model): | ||||
|         owner = models.ForeignKey('auth.user') | ||||
|         name = models.CharField(max_length=100) | ||||
|  | @ -85,13 +88,14 @@ For example, using the following model. | |||
|         payment_expiry = models.DateTimeField() | ||||
|          | ||||
|         def has_expired(self): | ||||
|             now = datetime.datetime.now() | ||||
|             return now > self.payment_expiry | ||||
|             return now() > self.payment_expiry | ||||
| 
 | ||||
| A serializer definition that looked like this: | ||||
| 
 | ||||
|     from rest_framework import serializers | ||||
| 
 | ||||
|     class AccountSerializer(serializers.HyperlinkedModelSerializer): | ||||
|         expired = Field(source='has_expired') | ||||
|         expired = serializers.Field(source='has_expired') | ||||
|          | ||||
|         class Meta: | ||||
|             fields = ('url', 'owner', 'name', 'expired') | ||||
|  | @ -125,12 +129,11 @@ The `ModelField` class is generally intended for internal use, but can be used b | |||
| 
 | ||||
| This is a read-only field.  It gets its value by calling a method on the serializer class it is attached to.  It can be used to add any sort of data to the serialized representation of your object.  The field's constructor accepts a single argument, which is the name of the method on the serializer to be called.  The method should accept a single argument (in addition to `self`), which is the object being serialized.  It should return whatever you want to be included in the serialized representation of the object.  For example: | ||||
| 
 | ||||
|     from rest_framework import serializers | ||||
|     from django.contrib.auth.models import User | ||||
|     from django.utils.timezone import now | ||||
|     from rest_framework import serializers | ||||
| 
 | ||||
|     class UserSerializer(serializers.ModelSerializer): | ||||
| 
 | ||||
|         days_since_joined = serializers.SerializerMethodField('get_days_since_joined') | ||||
| 
 | ||||
|         class Meta: | ||||
|  |  | |||
|  | @ -20,6 +20,10 @@ You can do so by filtering based on the value of `request.user`. | |||
| 
 | ||||
| For example: | ||||
| 
 | ||||
|     from myapp.models import Purchase | ||||
|     from myapp.serializers import PurchaseSerializer | ||||
|     from rest_framework import generics | ||||
| 
 | ||||
|     class PurchaseList(generics.ListAPIView) | ||||
|         serializer_class = PurchaseSerializer | ||||
|   | ||||
|  | @ -90,6 +94,11 @@ The default filter backends may be set globally, using the `DEFAULT_FILTER_BACKE | |||
| You can also set the filter backends on a per-view, or per-viewset basis, | ||||
| using the `GenericAPIView` class based views. | ||||
| 
 | ||||
|     from django.contrib.auth.models import User | ||||
| 	from myapp.serializers import UserSerializer | ||||
|     from rest_framework import filters | ||||
| 	from rest_framework import generics | ||||
| 
 | ||||
|     class UserListView(generics.ListAPIView): | ||||
|         queryset = User.objects.all() | ||||
|         serializer = UserSerializer | ||||
|  | @ -150,6 +159,11 @@ This will automatically create a `FilterSet` class for the given fields, and wil | |||
| 
 | ||||
| For more advanced filtering requirements you can specify a `FilterSet` class that should be used by the view.  For example: | ||||
| 
 | ||||
|     import django_filters | ||||
|     from myapp.models import Product | ||||
|     from myapp.serializers import ProductSerializer | ||||
|     from rest_framework import generics | ||||
| 
 | ||||
|     class ProductFilter(django_filters.FilterSet): | ||||
|         min_price = django_filters.NumberFilter(lookup_type='gte') | ||||
|         max_price = django_filters.NumberFilter(lookup_type='lte') | ||||
|  |  | |||
|  | @ -17,6 +17,11 @@ If the generic views don't suit the needs of your API, you can drop down to usin | |||
| 
 | ||||
| Typically when using the generic views, you'll override the view, and set several class attributes. | ||||
| 
 | ||||
|     from django.contrib.auth.models import User | ||||
|     from myapp.serializers import UserSerializer | ||||
| 	from rest_framework import generics | ||||
| 	from rest_framework.permissions import IsAdminUser | ||||
| 
 | ||||
|     class UserList(generics.ListCreateAPIView): | ||||
|         queryset = User.objects.all() | ||||
|         serializer_class = UserSerializer | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ REST framework includes a `PaginationSerializer` class that makes it easy to ret | |||
| Let's start by taking a look at an example from the Django documentation. | ||||
| 
 | ||||
|     from django.core.paginator import Paginator | ||||
| 
 | ||||
|     objects = ['john', 'paul', 'george', 'ringo'] | ||||
|     paginator = Paginator(objects, 2) | ||||
|     page = paginator.page(1) | ||||
|  | @ -22,6 +23,7 @@ Let's start by taking a look at an example from the Django documentation. | |||
| At this point we've got a page object.  If we wanted to return this page object as a JSON response, we'd need to provide the client with context such as next and previous links, so that it would be able to page through the remaining results. | ||||
| 
 | ||||
|     from rest_framework.pagination import PaginationSerializer | ||||
| 
 | ||||
|     serializer = PaginationSerializer(instance=page) | ||||
|     serializer.data | ||||
|     # {'count': 4, 'next': '?page=2', 'previous': None, 'results': [u'john', u'paul']} | ||||
|  | @ -114,6 +116,9 @@ You can also override the name used for the object list field, by setting the `r | |||
| 
 | ||||
| For example, to nest a pair of links labelled 'prev' and 'next', and set the name for the results field to 'objects', you might use something like this. | ||||
| 
 | ||||
|     from rest_framework import pagination | ||||
|     from rest_framework import serializers | ||||
| 
 | ||||
|     class LinksSerializer(serializers.Serializer): | ||||
|         next = pagination.NextPageField(source='*') | ||||
|         prev = pagination.PreviousPageField(source='*') | ||||
|  | @ -135,7 +140,7 @@ To have your custom pagination serializer be used by default, use the `DEFAULT_P | |||
| 
 | ||||
| Alternatively, to set your custom pagination serializer on a per-view basis, use the `pagination_serializer_class` attribute on a generic class based view: | ||||
| 
 | ||||
|     class PaginatedListView(ListAPIView): | ||||
|     class PaginatedListView(generics.ListAPIView): | ||||
|         model = ExampleModel | ||||
|         pagination_serializer_class = CustomPaginationSerializer | ||||
|         paginate_by = 10 | ||||
|  |  | |||
|  | @ -37,6 +37,10 @@ The default set of parsers may be set globally, using the `DEFAULT_PARSER_CLASSE | |||
| You can also set the renderers used for an individual view, or viewset, | ||||
| using the `APIView` class based views. | ||||
| 
 | ||||
| 	from rest_framework.parsers import YAMLParser | ||||
| 	from rest_framework.response import Response | ||||
|     from rest_framework.views import APIView | ||||
| 
 | ||||
|     class ExampleView(APIView): | ||||
|         """ | ||||
|         A view that can accept POST requests with YAML content. | ||||
|  |  | |||
|  | @ -47,6 +47,10 @@ If not specified, this setting defaults to allowing unrestricted access: | |||
| You can also set the authentication policy on a per-view, or per-viewset basis, | ||||
| using the `APIView` class based views. | ||||
| 
 | ||||
|     from rest_framework.permissions import IsAuthenticated | ||||
| 	from rest_framework.responses import Response | ||||
| 	from rest_framework.views import APIView | ||||
| 
 | ||||
|     class ExampleView(APIView): | ||||
|         permission_classes = (IsAuthenticated,) | ||||
| 
 | ||||
|  | @ -157,6 +161,8 @@ For more details see the [2.2 release announcement][2.2-announcement]. | |||
| 
 | ||||
| The following is an example of a permission class that checks the incoming request's IP address against a blacklist, and denies the request if the IP has been blacklisted. | ||||
| 
 | ||||
|     from rest_framework import permissions | ||||
| 
 | ||||
|     class BlacklistPermission(permissions.BasePermission): | ||||
|         """ | ||||
|         Global permission check for blacklisted IPs. | ||||
|  |  | |||
|  | @ -76,7 +76,7 @@ This field is read only. | |||
| For example, the following serializer: | ||||
|   | ||||
|     class AlbumSerializer(serializers.ModelSerializer): | ||||
|         tracks = PrimaryKeyRelatedField(many=True, read_only=True) | ||||
|         tracks = serializers.PrimaryKeyRelatedField(many=True, read_only=True) | ||||
|          | ||||
|         class Meta: | ||||
|             model = Album | ||||
|  | @ -110,8 +110,8 @@ By default this field is read-write, although you can change this behavior using | |||
| For example, the following serializer: | ||||
|   | ||||
|     class AlbumSerializer(serializers.ModelSerializer): | ||||
|         tracks = HyperlinkedRelatedField(many=True, read_only=True, | ||||
|                                          view_name='track-detail') | ||||
|         tracks = serializers.HyperlinkedRelatedField(many=True, read_only=True, | ||||
|                                                      view_name='track-detail') | ||||
|          | ||||
|         class Meta: | ||||
|             model = Album | ||||
|  | @ -148,7 +148,8 @@ By default this field is read-write, although you can change this behavior using | |||
| For example, the following serializer: | ||||
|   | ||||
|     class AlbumSerializer(serializers.ModelSerializer): | ||||
|         tracks = SlugRelatedField(many=True, read_only=True, slug_field='title') | ||||
|         tracks = serializers.SlugRelatedField(many=True, read_only=True, | ||||
|                                               slug_field='title') | ||||
|          | ||||
|         class Meta: | ||||
|             model = Album | ||||
|  | @ -183,7 +184,7 @@ When using `SlugRelatedField` as a read-write field, you will normally want to e | |||
| This field can be applied as an identity relationship, such as the `'url'` field on  a HyperlinkedModelSerializer.  It can also be used for an attribute on the object.  For example, the following serializer: | ||||
| 
 | ||||
|     class AlbumSerializer(serializers.HyperlinkedModelSerializer): | ||||
|         track_listing = HyperlinkedIdentityField(view_name='track-list') | ||||
|         track_listing = serializers.HyperlinkedIdentityField(view_name='track-list') | ||||
| 
 | ||||
|         class Meta: | ||||
|             model = Album | ||||
|  |  | |||
|  | @ -30,11 +30,16 @@ The default set of renderers may be set globally, using the `DEFAULT_RENDERER_CL | |||
| You can also set the renderers used for an individual view, or viewset, | ||||
| using the `APIView` class based views. | ||||
| 
 | ||||
|     from django.contrib.auth.models import User | ||||
|     from rest_framework.renderers import JSONRenderer, YAMLRenderer | ||||
|     from rest_framework.response import Response | ||||
|     from rest_framework.views import APIView | ||||
| 
 | ||||
|     class UserCountView(APIView): | ||||
|         """ | ||||
|         A view that returns the count of active users, in JSON or JSONp. | ||||
|         A view that returns the count of active users, in JSON or YAML. | ||||
|         """ | ||||
|         renderer_classes = (JSONRenderer, JSONPRenderer) | ||||
|         renderer_classes = (JSONRenderer, YAMLRenderer) | ||||
| 
 | ||||
|         def get(self, request, format=None): | ||||
|             user_count = User.objects.filter(active=True).count() | ||||
|  |  | |||
|  | @ -27,13 +27,13 @@ Has the same behavior as [`django.core.urlresolvers.reverse`][reverse], except t | |||
| 
 | ||||
| You should **include the request as a keyword argument** to the function, for example: | ||||
| 
 | ||||
|     import datetime | ||||
|     from rest_framework.reverse import reverse | ||||
|     from rest_framework.views import APIView | ||||
| 	from django.utils.timezone import now | ||||
|     | ||||
| 	class APIRootView(APIView): | ||||
| 	    def get(self, request): | ||||
| 	        year = datetime.datetime.now().year | ||||
| 	        year = now().year | ||||
| 			data = { | ||||
|  				... | ||||
|     		    'year-summary-url': reverse('year-summary', args=[year], request=request) | ||||
|  |  | |||
|  | @ -14,6 +14,8 @@ REST framework adds support for automatic URL routing to Django, and provides yo | |||
| 
 | ||||
| Here's an example of a simple URL conf, that uses `DefaultRouter`. | ||||
| 
 | ||||
|     from rest_framework import routers | ||||
| 
 | ||||
|     router = routers.SimpleRouter() | ||||
|     router.register(r'users', UserViewSet) | ||||
|     router.register(r'accounts', AccountViewSet) | ||||
|  | @ -40,6 +42,9 @@ The example above would generate the following URL patterns: | |||
| Any methods on the viewset decorated with `@link` or `@action` will also be routed. | ||||
| For example, given a method like this on the `UserViewSet` class: | ||||
| 
 | ||||
| 	from myapp.permissions import IsAdminOrIsSelf | ||||
|     from rest_framework.decorators import action | ||||
| 
 | ||||
|     @action(permission_classes=[IsAdminOrIsSelf]) | ||||
|     def set_password(self, request, pk=None): | ||||
|         ... | ||||
|  | @ -120,6 +125,8 @@ The arguments to the `Route` named tuple are: | |||
| 
 | ||||
| The following example will only route to the `list` and `retrieve` actions, and does not use the trailing slash convention. | ||||
| 
 | ||||
|     from rest_framework.routers import Route, SimpleRouter | ||||
| 
 | ||||
|     class ReadOnlyRouter(SimpleRouter): | ||||
|         """ | ||||
|         A router for read-only APIs, which doesn't use trailing slashes. | ||||
|  |  | |||
|  | @ -28,6 +28,8 @@ We'll declare a serializer that we can use to serialize and deserialize `Comment | |||
| 
 | ||||
| Declaring a serializer looks very similar to declaring a form: | ||||
| 
 | ||||
|     from rest_framework import serializers | ||||
| 
 | ||||
|     class CommentSerializer(serializers.Serializer): | ||||
|         email = serializers.EmailField() | ||||
|         content = serializers.CharField(max_length=200) | ||||
|  | @ -59,6 +61,8 @@ We can now use `CommentSerializer` to serialize a comment, or list of comments. | |||
| 
 | ||||
| At this point we've translated the model instance into Python native datatypes.  To finalise the serialization process we render the data into `json`. | ||||
| 
 | ||||
|     from rest_framework.renderers import JSONRenderer | ||||
| 
 | ||||
|     json = JSONRenderer().render(serializer.data) | ||||
|     json | ||||
|     # '{"email": "leila@example.com", "content": "foo bar", "created": "2012-08-22T16:20:09.822"}' | ||||
|  | @ -67,6 +71,9 @@ At this point we've translated the model instance into Python native datatypes. | |||
|          | ||||
| Deserialization is similar.  First we parse a stream into Python native datatypes...  | ||||
| 
 | ||||
|     from StringIO import StringIO | ||||
|     from rest_framework.parsers import JSONParser | ||||
| 
 | ||||
|     stream = StringIO(json) | ||||
|     data = JSONParser().parse(stream) | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ | |||
| Using bare status codes in your responses isn't recommended.  REST framework includes a set of named constants that you can use to make more code more obvious and readable. | ||||
| 
 | ||||
|     from rest_framework import status | ||||
|     from rest_framework.response import Response | ||||
| 
 | ||||
|     def empty_view(self): | ||||
|         content = {'please move along': 'nothing to see here'} | ||||
|  |  | |||
|  | @ -16,6 +16,8 @@ Extends [Django's existing `RequestFactory` class][requestfactory]. | |||
| 
 | ||||
| The `APIRequestFactory` class supports an almost identical API to Django's standard `RequestFactory` class.  This means the that standard `.get()`, `.post()`, `.put()`, `.patch()`, `.delete()`, `.head()` and `.options()` methods are all available. | ||||
| 
 | ||||
|     from rest_framework.test import APIRequestFactory | ||||
| 
 | ||||
|     # Using the standard RequestFactory API to create a form POST request | ||||
|     factory = APIRequestFactory() | ||||
|     request = factory.post('/notes/', {'title': 'new idea'}) | ||||
|  | @ -49,6 +51,8 @@ For example, using `APIRequestFactory`, you can make a form PUT request like so: | |||
| 
 | ||||
| Using Django's `RequestFactory`, you'd need to explicitly encode the data yourself: | ||||
| 
 | ||||
|     from django.test.client import encode_multipart, RequestFactory | ||||
| 
 | ||||
|     factory = RequestFactory() | ||||
|     data = {'title': 'remember to email dave'} | ||||
|     content = encode_multipart('BoUnDaRyStRiNg', data) | ||||
|  | @ -72,6 +76,12 @@ To forcibly authenticate a request, use the `force_authenticate()` method. | |||
| 
 | ||||
| The signature for the method is `force_authenticate(request, user=None, token=None)`.  When making the call, either or both of the user and token may be set. | ||||
| 
 | ||||
| For example, when forcibly authenticating using a token, you might do something like the following: | ||||
| 
 | ||||
|     user = User.objects.get(username='olivia') | ||||
|     request = factory.get('/accounts/django-superstars/') | ||||
|     force_authenticate(request, user=user, token=user.token) | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| **Note**: When using `APIRequestFactory`, the object that is returned is Django's standard `HttpRequest`, and not REST framework's `Request` object, which is only generated once the view is called. | ||||
|  | @ -105,6 +115,8 @@ Extends [Django's existing `Client` class][client]. | |||
| 
 | ||||
| The `APIClient` class supports the same request interface as `APIRequestFactory`.  This means the that standard `.get()`, `.post()`, `.put()`, `.patch()`, `.delete()`, `.head()` and `.options()` methods are all available.  For example: | ||||
| 
 | ||||
|     from rest_framework.test import APIClient | ||||
| 
 | ||||
|     client = APIClient() | ||||
|     client.post('/notes/', {'title': 'new idea'}, format='json') | ||||
| 
 | ||||
|  | @ -131,8 +143,11 @@ The `login` method is appropriate for testing APIs that use session authenticati | |||
| 
 | ||||
| The `credentials` method can be used to set headers that will then be included on all subsequent requests by the test client. | ||||
| 
 | ||||
|     from rest_framework.authtoken.models import Token | ||||
|     from rest_framework.test import APIClient | ||||
| 
 | ||||
|     # Include an appropriate `Authorization:` header on all requests. | ||||
|     token = Token.objects.get(username='lauren') | ||||
|     token = Token.objects.get(user__username='lauren') | ||||
|     client = APIClient() | ||||
|     client.credentials(HTTP_AUTHORIZATION='Token ' + token.key) | ||||
| 
 | ||||
|  | @ -190,10 +205,10 @@ You can use any of REST framework's test case classes as you would for the regul | |||
|             Ensure we can create a new account object. | ||||
|             """ | ||||
|             url = reverse('account-list') | ||||
|             data = {'name': 'DabApps'} | ||||
|             expected = {'name': 'DabApps'} | ||||
|             response = self.client.post(url, data, format='json') | ||||
|             self.assertEqual(response.status_code, status.HTTP_201_CREATED) | ||||
|             self.assertEqual(response.data, data) | ||||
|             self.assertEqual(response.data, expected) | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
|  |  | |||
|  | @ -43,6 +43,10 @@ The rate descriptions used in `DEFAULT_THROTTLE_RATES` may include `second`, `mi | |||
| You can also set the throttling policy on a per-view or per-viewset basis, | ||||
| using the `APIView` class based views. | ||||
| 
 | ||||
| 	from rest_framework.response import Response | ||||
|     from rest_framework.throttling import UserRateThrottle | ||||
| 	from rest_framework.views import APIView | ||||
| 
 | ||||
|     class ExampleView(APIView): | ||||
|         throttle_classes = (UserRateThrottle,) | ||||
| 
 | ||||
|  |  | |||
|  | @ -19,6 +19,12 @@ Typically, rather than explicitly registering the views in a viewset in the urlc | |||
| 
 | ||||
| Let's define a simple viewset that can be used to list or retrieve all the users in the system. | ||||
| 
 | ||||
|     from django.contrib.auth.models import User | ||||
|     from django.shortcuts import get_object_or_404 | ||||
|     from myapps.serializers import UserSerializer | ||||
|     from rest_framework import viewsets | ||||
|     from rest_framewor.responses import Response | ||||
| 
 | ||||
|     class UserViewSet(viewsets.ViewSet): | ||||
|         """ | ||||
|         A simple ViewSet that for listing or retrieving users. | ||||
|  | @ -41,6 +47,9 @@ If we need to, we can bind this viewset into two separate views, like so: | |||
| 
 | ||||
| Typically we wouldn't do this, but would instead register the viewset with a router, and allow the urlconf to be automatically generated. | ||||
| 
 | ||||
|     from myapp.views import UserViewSet | ||||
|     from rest_framework.routers import DefaultRouter | ||||
| 
 | ||||
|     router = DefaultRouter() | ||||
|     router.register(r'users', UserViewSet) | ||||
|     urlpatterns = router.urls | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user