Deprecate .model attribute on views

This commit is contained in:
Tom Christie 2014-08-20 16:24:52 +01:00
parent 59b47eac14
commit 9372cc8c31
4 changed files with 100 additions and 64 deletions

View File

@ -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].

View File

@ -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

View File

@ -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].

View File

@ -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'"