mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-10 19:56:59 +03:00
Added quickstart guide
This commit is contained in:
parent
dc52ceaaa2
commit
115e61be09
|
@ -58,6 +58,7 @@ Note that the base URL can be whatever you want, but you must include `rest_fram
|
|||
|
||||
## Quickstart
|
||||
|
||||
Can't wait to get started? The [quickstart guide][quickstart] is the fastest way to get up and running with REST framework.
|
||||
|
||||
## Tutorial
|
||||
|
||||
|
@ -118,6 +119,12 @@ Run the tests:
|
|||
|
||||
./rest_framework/runtests/runtests.py
|
||||
|
||||
## Support
|
||||
|
||||
For support please see the [REST framework discussion group][group], or try the `#restframework` channel on `irc.freenode.net`.
|
||||
|
||||
Paid support is also available from [DabApps], and can include work on REST framework core, or support with building your REST framework API. Please contact [Tom Christie][email] if you'd like to discuss commercial support options.
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2011-2012, Tom Christie
|
||||
|
@ -149,6 +156,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
[markdown]: http://pypi.python.org/pypi/Markdown/
|
||||
[yaml]: http://pypi.python.org/pypi/PyYAML
|
||||
|
||||
[quickstart]: tutorial/quickstart.md
|
||||
[tut-1]: tutorial/1-serialization.md
|
||||
[tut-2]: tutorial/2-requests-and-responses.md
|
||||
[tut-3]: tutorial/3-class-based-views.md
|
||||
|
@ -183,3 +191,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
[migration]: topics/migration.md
|
||||
[changelog]: topics/changelog.md
|
||||
[credits]: topics/credits.md
|
||||
|
||||
[group]: https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework
|
||||
[DabApps]: http://dabapps.com
|
||||
[email]: mailto:tom@tomchristie.com
|
|
@ -37,6 +37,7 @@
|
|||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorial <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{{ base_url }}/tutorial/quickstart{{ suffix }}">Quickstart</a></li>
|
||||
<li><a href="{{ base_url }}/tutorial/1-serialization{{ suffix }}">1 - Serialization</a></li>
|
||||
<li><a href="{{ base_url }}/tutorial/2-requests-and-responses{{ suffix }}">2 - Requests and responses</a></li>
|
||||
<li><a href="{{ base_url }}/tutorial/3-class-based-views{{ suffix }}">3 - Class based views</a></li>
|
||||
|
|
133
docs/tutorial/quickstart.md
Normal file
133
docs/tutorial/quickstart.md
Normal file
|
@ -0,0 +1,133 @@
|
|||
# Quickstart
|
||||
|
||||
We're going to create a simple API to allow admin users to view and edit the users and groups in the system.
|
||||
|
||||
Create a new Django project, and start a new app called `quickstart`. 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.
|
||||
|
||||
from django.contrib.auth.models import User, Group
|
||||
from rest_framework import serializers
|
||||
|
||||
|
||||
class UserSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ('url', 'username', 'email', 'groups')
|
||||
|
||||
|
||||
class GroupSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = Group
|
||||
fields = ('url', 'name', 'permissions')
|
||||
|
||||
Notice that we're using hyperlinked relations in this case, with `HyperlinkedModelSerializer`. You can also use primary key and various other relationships, but hyperlinking is good RESTful design.
|
||||
|
||||
## Views
|
||||
|
||||
Right, we'd better right some views then. Open `quickstart/views.py` and get typing.
|
||||
|
||||
from django.contrib.auth.models import User, Group
|
||||
from rest_framework import generics
|
||||
from rest_framework.decorators import api_view
|
||||
from rest_framework.reverse import reverse
|
||||
from rest_framework.response import Response
|
||||
from quickstart.serializers import UserSerializer, GroupSerializer
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
def api_root(request, format=None):
|
||||
"""
|
||||
The entry endpoint of our API.
|
||||
"""
|
||||
return Response({
|
||||
'users': reverse('user-list', request=request),
|
||||
'groups': reverse('group-list', request=request),
|
||||
})
|
||||
|
||||
|
||||
class UserList(generics.ListCreateAPIView):
|
||||
"""
|
||||
API endpoint that represents a list of users.
|
||||
"""
|
||||
model = User
|
||||
serializer_class = UserSerializer
|
||||
|
||||
|
||||
class UserDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||
"""
|
||||
API endpoint that represents a single user.
|
||||
"""
|
||||
model = User
|
||||
serializer_class = UserSerializer
|
||||
|
||||
|
||||
class GroupList(generics.ListCreateAPIView):
|
||||
"""
|
||||
API endpoint that represents a list of groups.
|
||||
"""
|
||||
model = Group
|
||||
serializer_class = GroupSerializer
|
||||
|
||||
|
||||
class GroupDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||
"""
|
||||
API endpoint that represents a single group.
|
||||
"""
|
||||
model = Group
|
||||
serializer_class = GroupSerializer
|
||||
|
||||
Let's take a moment to look at what we've done here before we move on. We have one function-based view representing the root of the API, and four class-based views which map to our database models, and specify which serializers should be used for representing that data. Pretty simple stuff.
|
||||
|
||||
## URLs
|
||||
|
||||
Okay, let's wire this baby up. On to `quickstart/urls.py`...
|
||||
|
||||
from django.conf.urls import patterns, url, include
|
||||
from rest_framework.urlpatterns import format_suffix_patterns
|
||||
from quickstart.views import UserList, UserDetail, GroupList, GroupDetail
|
||||
|
||||
|
||||
urlpatterns = patterns('quickstart.views',
|
||||
url(r'^$', 'api_root'),
|
||||
url(r'^users/$', UserList.as_view(), name='user-list'),
|
||||
url(r'^users/(?P<pk>\d+)/$', UserDetail.as_view(), name='user-detail'),
|
||||
url(r'^groups/$', GroupList.as_view(), name='group-list'),
|
||||
url(r'^groups/(?P<pk>\d+)/$', GroupDetail.as_view(), name='group-detail'),
|
||||
)
|
||||
|
||||
|
||||
# Format suffixes
|
||||
urlpatterns = format_suffix_patterns(urlpatterns, allowed=['json', 'api'])
|
||||
|
||||
|
||||
# Default login/logout views
|
||||
urlpatterns += patterns('',
|
||||
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
|
||||
)
|
||||
|
||||
There's a few things worth noting here.
|
||||
|
||||
Firstly the names `user-detail` and `group-detail` are important. We're using the default hyperlinked relationships without explicitly specifying the view names, so we need to use names of the style `{modelname}-detail` to represent the model instance views.
|
||||
|
||||
Secondly, we're modifying the urlpatterns using `format_suffix_patterns`, to append optional `.json` style suffixes to our URLs.
|
||||
|
||||
Finally, we're including default login and logout views for use with the browsable API. That's optional, but useful if your API requires authentication and you want to use the browseable API.
|
||||
|
||||
## Settings
|
||||
|
||||
We'd also like to set a few global settings. We'd like to turn on pagination, and we want our API to only be accessible to admin users.
|
||||
|
||||
INSTALLED_APPS = (
|
||||
...
|
||||
'rest_framework',
|
||||
)
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
'PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser'),
|
||||
'PAGINATE_BY': 10
|
||||
}
|
||||
|
||||
Okay, that's us done.
|
|
@ -13,7 +13,8 @@ def api_view(http_method_names):
|
|||
class WrappedAPIView(APIView):
|
||||
pass
|
||||
|
||||
WrappedAPIView.http_method_names = [method.lower() for method in http_method_names]
|
||||
allowed_methods = set(http_method_names) | set(('options',))
|
||||
WrappedAPIView.http_method_names = [method.lower() for method in allowed_methods]
|
||||
|
||||
def handler(self, *args, **kwargs):
|
||||
return func(*args, **kwargs)
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
{% if user.is_authenticated %}
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
Welcome, {{ user }}
|
||||
Logged in as {{ user }}
|
||||
<b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
|
|
|
@ -2,13 +2,34 @@ from django.conf.urls.defaults import url
|
|||
from rest_framework.settings import api_settings
|
||||
|
||||
|
||||
def format_suffix_patterns(urlpatterns, suffix_required=False, suffix_kwarg=None):
|
||||
def format_suffix_patterns(urlpatterns, suffix_required=False,
|
||||
suffix_kwarg=None, allowed=None):
|
||||
"""
|
||||
Supplement existing urlpatterns with corrosponding patterns that also
|
||||
include a '.format' suffix. Retains urlpattern ordering.
|
||||
|
||||
suffix_required:
|
||||
If `True`, only suffixed URLs will be generated, and non-suffixed
|
||||
URLs will not be used. Defaults to `False`.
|
||||
|
||||
suffix_kwarg:
|
||||
The name of the kwarg that will be passed to the view.
|
||||
Defaults to 'format'.
|
||||
|
||||
allowed:
|
||||
An optional tuple/list of allowed suffixes. eg ['json', 'api']
|
||||
Defaults to `None`, which allows any suffix.
|
||||
|
||||
"""
|
||||
suffix_kwarg = suffix_kwarg or api_settings.FORMAT_SUFFIX_KWARG
|
||||
suffix_pattern = r'\.(?P<%s>[a-z]+)$' % suffix_kwarg
|
||||
if allowed:
|
||||
if len(allowed) == 1:
|
||||
allowed_pattern = allowed[0]
|
||||
else:
|
||||
allowed_pattern = '(%s)' % '|'.join(allowed)
|
||||
suffix_pattern = r'\.(?P<%s>%s)$' % (suffix_kwarg, allowed_pattern)
|
||||
else:
|
||||
suffix_pattern = r'\.(?P<%s>[a-z]+)$' % suffix_kwarg
|
||||
|
||||
ret = []
|
||||
for urlpattern in urlpatterns:
|
||||
|
|
Loading…
Reference in New Issue
Block a user