diff --git a/README.md b/README.md index 7052ab638..d33177399 100644 --- a/README.md +++ b/README.md @@ -39,40 +39,51 @@ Add `'rest_framework'` to your `INSTALLED_APPS` setting. INSTALLED_APPS = ( ... - 'rest_framework', + 'rest_framework', ) # Example Let's take a look at a quick example of using REST framework to build a simple model-backed API for accessing users and groups. -Here's our project's root `urls.py` module: +Startup up a new project like so... + + pip install django + pip install djangorestframework + django-admin startproject example . + ./manage.py syncdb + +Now edit the `example/urls.py` module in your project: ```python -from django.conf.urls.defaults import url, patterns, include -from django.contrib.auth.models import User, Group -from rest_framework import viewsets, routers +from django.conf.urls import url, include +from django.contrib.auth.models import User +from rest_framework import serializers, viewsets, routers + +# Serializers define the API representation. +class UserSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = User + fields = ('url', 'username', 'email', 'is_staff') + # ViewSets define the view behavior. class UserViewSet(viewsets.ModelViewSet): - model = User - -class GroupViewSet(viewsets.ModelViewSet): - model = Group + queryset = User.objects.all() + serializer_class = UserSerializer -# Routers provide an easy way of automatically determining the URL conf +# Routers provide a way of automatically determining the URL conf. router = routers.DefaultRouter() router.register(r'users', UserViewSet) -router.register(r'groups', GroupViewSet) # Wire up our API using automatic URL routing. # Additionally, we include login URLs for the browseable API. -urlpatterns = patterns('', +urlpatterns = [ url(r'^', include(router.urls)), url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) -) +] ``` We'd also like to configure a couple of settings for our API. @@ -80,12 +91,12 @@ We'd also like to configure a couple of settings for our API. Add the following to your `settings.py` module: ```python -REST_FRAMEWORK = { - # Use hyperlinked styles by default. - # Only used if the `serializer_class` attribute is not set on a view. - 'DEFAULT_MODEL_SERIALIZER_CLASS': - 'rest_framework.serializers.HyperlinkedModelSerializer', +INSTALLED_APPS = ( + ... # Make sure to include the default installed apps here. + 'rest_framework', +) +REST_FRAMEWORK = { # Use Django's standard `django.contrib.auth` permissions, # or allow read-only access for unauthenticated users. 'DEFAULT_PERMISSION_CLASSES': [ @@ -93,10 +104,35 @@ REST_FRAMEWORK = { ] } ``` -Don't forget to make sure you've also added `rest_framework` to your `INSTALLED_APPS` setting. That's it, we're done! + ./manage.py runserver + +You can now open the API in your browser at `http://127.0.0.1:8000/`, and view your new 'users' API. If you use the `Login` control in the top right corner you'll also be able to add, create and delete users from the system. + +You can also interact with the API using command line tools such as [`curl`](http://curl.haxx.se/). For example, to list the users endpoint: + + $ curl -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/ + [ + { + "url": "http://127.0.0.1:8000/users/1/", + "username": "admin", + "email": "admin@example.com", + "is_staff": true, + } + ] + +Or to create a new user: + + $ curl -X POST -d username=new -d email=new@example.com -d is_staff=false -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/ + { + "url": "http://127.0.0.1:8000/users/2/", + "username": "new", + "email": "new@example.com", + "is_staff": false, + } + # Documentation & Support Full documentation for the project is available at [http://www.django-rest-framework.org][docs]. diff --git a/docs/index.md b/docs/index.md index 83e30a690..3e6d23aec 100644 --- a/docs/index.md +++ b/docs/index.md @@ -96,16 +96,11 @@ Note that the URL path can be whatever you want, but you must include `'rest_fra Let's take a look at a quick example of using REST framework to build a simple model-backed API. -We'll create a read-write API for accessing users and groups. +We'll create a read-write API for accessing information on the users of our project. Any global settings for a REST framework API are kept in a single configuration dictionary named `REST_FRAMEWORK`. Start off by adding the following to your `settings.py` module: REST_FRAMEWORK = { - # Use hyperlinked styles by default. - # Only used if the `serializer_class` attribute is not set on a view. - 'DEFAULT_MODEL_SERIALIZER_CLASS': - 'rest_framework.serializers.HyperlinkedModelSerializer', - # Use Django's standard `django.contrib.auth` permissions, # or allow read-only access for unauthenticated users. 'DEFAULT_PERMISSION_CLASSES': [ @@ -118,34 +113,37 @@ Don't forget to make sure you've also added `rest_framework` to your `INSTALLED_ We're ready to create our API now. Here's our project's root `urls.py` module: - from django.conf.urls import url, patterns, include - from django.contrib.auth.models import User, Group - from rest_framework import viewsets, routers + from django.conf.urls import url, include + from django.contrib.auth.models import User + from rest_framework import routers, serializers, viewsets + + # Serializers define the API representation. + class UserSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = User + fields = ('url', 'username', 'email', 'is_staff') # ViewSets define the view behavior. class UserViewSet(viewsets.ModelViewSet): - model = User - - class GroupViewSet(viewsets.ModelViewSet): - model = Group - + queryset = User.objects.all() + serializer_class = UserSerializer # Routers provide an easy way of automatically determining the URL conf. router = routers.DefaultRouter() router.register(r'users', UserViewSet) - router.register(r'groups', GroupViewSet) - # Wire up our API using automatic URL routing. # Additionally, we include login URLs for the browseable API. - urlpatterns = patterns('', + urlpatterns = [ url(r'^', include(router.urls)), url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) - ) + ] + +You can now open the API in your browser at [http://127.0.0.1:8000/](http://127.0.0.1:8000/), and view your new 'users' API. If you use the Login control in the top right corner you'll also be able to add, create and delete users from the system. ## Quickstart -Can't wait to get started? The [quickstart guide][quickstart] is the fastest way to get up and running, and building APIs with REST framework. +Can't wait to get started? The [quickstart guide][quickstart] is the fastest way to get up and running, and building APIs with REST framework. ## Tutorial diff --git a/docs/tutorial/quickstart.md b/docs/tutorial/quickstart.md index 98e5f439f..813e9872c 100644 --- a/docs/tutorial/quickstart.md +++ b/docs/tutorial/quickstart.md @@ -18,34 +18,23 @@ Create a new Django project named `tutorial`, then start a new app called `quick pip install django pip install djangorestframework - # Set up a new project - django-admin.py startproject tutorial + # Set up a new project with a single application + django-admin.py startproject tutorial . + cd tutorial + django-admin.py startapp quickstart + cd .. - # Create a new app - python manage.py startapp quickstart - -Next you'll need to get a database set up and synced. If you just want to use SQLite for now, then you'll want to edit your `tutorial/settings.py` module to include something like this: - - DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': 'database.sql', - 'USER': '', - 'PASSWORD': '', - 'HOST': '', - 'PORT': '' - } - } - -The run `syncdb` like so: +Now sync your database for the first time: python manage.py syncdb +Make sure to create an initial user named `admin` with a password of `password`. We'll authenticate as that user later in our example. + Once you've set up a database and got everything synced and ready to go, open up the app's directory and we'll get coding... ## Serializers -First up we're going to define some serializers in `quickstart/serializers.py` that we'll use for our data representations. +First up we're going to define some serializers. Let's create a new module named `tutorial/quickstart/serializers.py` that we'll use for our data representations. from django.contrib.auth.models import User, Group from rest_framework import serializers @@ -66,11 +55,11 @@ Notice that we're using hyperlinked relations in this case, with `HyperlinkedMod ## Views -Right, we'd better write some views then. Open `quickstart/views.py` and get typing. +Right, we'd better write some views then. Open `tutorial/quickstart/views.py` and get typing. from django.contrib.auth.models import User, Group from rest_framework import viewsets - from quickstart.serializers import UserSerializer, GroupSerializer + from tutorial.quickstart.serializers import UserSerializer, GroupSerializer class UserViewSet(viewsets.ModelViewSet): @@ -100,9 +89,9 @@ For trivial cases you can simply set a `model` attribute on the `ViewSet` class Okay, now let's wire up the API URLs. On to `tutorial/urls.py`... - from django.conf.urls import patterns, url, include + from django.conf.urls import url, include from rest_framework import routers - from quickstart import views + from tutorial.quickstart import views router = routers.DefaultRouter() router.register(r'users', views.UserViewSet) @@ -110,10 +99,10 @@ Okay, now let's wire up the API URLs. On to `tutorial/urls.py`... # Wire up our API using automatic URL routing. # Additionally, we include login URLs for the browseable API. - urlpatterns = patterns('', + urlpatterns = [ url(r'^', include(router.urls)), url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) - ) + ] Because we're using viewsets instead of views, we can automatically generate the URL conf for our API, by simply registering the viewsets with a router class. @@ -172,6 +161,8 @@ Or directly through the browser... ![Quick start image][image] +If you're working through the browser, make sure to login using the control in the top right corner. + Great, that was easy! If you want to get a more in depth understanding of how REST framework fits together head on over to [the tutorial][tutorial], or start browsing the [API guide][guide]. diff --git a/rest_framework/generics.py b/rest_framework/generics.py index 77deb8e4f..a6f686571 100644 --- a/rest_framework/generics.py +++ b/rest_framework/generics.py @@ -252,6 +252,12 @@ class GenericAPIView(views.APIView): if serializer_class is not None: return serializer_class + warnings.warn( + 'The `.model` attribute on view classes is now deprecated in favor ' + 'of the more explicit `serializer_class` and `queryset` attributes.', + DeprecationWarning, stacklevel=2 + ) + assert self.model is not None, \ "'%s' should either include a 'serializer_class' attribute, " \ "or use the 'model' attribute as a shortcut for " \ @@ -282,6 +288,11 @@ class GenericAPIView(views.APIView): return self.queryset._clone() if self.model is not None: + warnings.warn( + 'The `.model` attribute on view classes is now deprecated in favor ' + 'of the more explicit `serializer_class` and `queryset` attributes.', + DeprecationWarning, stacklevel=2 + ) return self.model._default_manager.all() error_format = "'%s' must define 'queryset' or 'model'"