Django Rest Framework 入門指南

Django Rest Framework (DRF) is powerful, sophisticated, and surprisingly easy to use. It offers an attractive, web browseable version of your API, and the option of returning raw JSON. The Django Rest Framework provides powerful model serialization, display data using standard function based views, or get granular with powerful class based views for more complex functionality. All in a fully REST compliant wrapper.

Working With Serialization

One powerful feature of the Django Rest Framework is the built in model serialization it offers. With just a few lines of code you can compose powerful representations of your data that can be delivered in a number of formats.

新建 App
startapp base
創建 models
# base/models.py
# -*- coding:utf-8 -*-
from django.db import models


class Author(models.Model):
    first_name = models.CharField(max_length=200)
    last_name = models.CharField(max_length=200)

    def __unicode__(self):
        return '{} {}'.format(self.first_name, self.last_name)


class Book(models.Model):
    title = models.CharField(max_length=200)
    isbn = models.CharField(max_length=20)
    author = models.ForeignKey(Author, related_name='books')

    def __unicode__(self):
        return self.title
添加數據到 SQLite database

** Author **

1   Andy    Matthews
2   China   Mieville

** Book **

1   jQuery Mobile Web Development Essentials    1849517266  1
2   jQuery Mobile Web Development Essentials    1849517266  2
3   Railsea 0345524535  2
```
##### 創建 serializer
```
# base/serializers.py
# -*- coding:utf-8 -*-
from rest_framework import serializers
from .models import Author


class AuthorSerializer(serializers.ModelSerializer):
    """
    Serializing all the Authors
    """
    class Meta:
        model = Author
        fields = ('id', 'first_name', 'last_name')
```
##### 通過 shell 查看序列化數據
```
>>> from base.models import Author
>>> from base.serializers import AuthorSerializer
>>> author = Author.objects.get(pk=1)
>>> serialized = AuthorSerializer(author)
>>> serialized.data
{'first_name': u'Andy', 'last_name': u'Matthews', 'id': 1}
```
##### Web Browseable API
```
# base/views.py
# -*- coding:utf-8 -*-
from rest_framework.generics import ListAPIView
from .models import Author
from .serializers import AuthorSerializer


class AuthorView(ListAPIView):
    """
    Returns a list of all authors.
    """
    queryset = Author.objects.all()
    serializer_class = AuthorSerializer
```

```
# -*- coding:utf-8 -*-
from django.conf.urls import url
from .views import AuthorView


urlpatterns = [
    url(r'^authors/$', AuthorView.as_view(), name='author-list'),

]
```
接下來通過瀏覽器訪問:http://127.0.0.1:8000/api/authors/

![](http://upload-images.jianshu.io/upload_images/2733312-11835c4d24b01f98.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

#### Giving the Authors Some Books!
在 `AuthorSerializer` 之前添加 `BookSerializer`:
```
class BookSerializer(serializers.ModelSerializer):
    """
    Serializing all the Books
    """
    class Meta:
        model = Book
        fields = ('id', 'title', 'isbn')
```
修改 `AuthorSerializer`:
```
class AuthorSerializer(serializers.ModelSerializer):
    """
    Serializing all the Authors
    """
    books = BookSerializer(many=True)

    class Meta:
        model = Author
        fields = ('id', 'first_name', 'last_name', 'books')
```
訪問:http://127.0.0.1:8000/api/authors/
![](http://upload-images.jianshu.io/upload_images/2733312-0fc64cf2ab12aeb0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

#### CRUD
** base/serializers.py **
```
# -*- coding:utf-8 -*-
from rest_framework import serializers
from rest_framework.generics import get_object_or_404
from .models import Author, Book


class BookSerializer(serializers.ModelSerializer):
    """
    Serializing all the Books
    """
    book_id = serializers.CharField(source='id', read_only=True)  #  the source allows you to explicitly name it something else when returning it to the end user.
    author_id = serializers.IntegerField(source='author.id', read_only=True)
    search_url = serializers.SerializerMethodField()  # Use SerializerMethodField to Create Custom Properties

    def get_search_url(self, obj):
        return "http://www.isbnsearch.org/isbn/{}".format(obj.isbn)

    class Meta:
        model = Book
        fields = ('book_id', 'title', 'isbn', 'author_id', 'search_url')


class AuthorSerializer(serializers.ModelSerializer):
    """
    Serializing all the Authors
    """
    id = serializers.ReadOnlyField()
    books = BookSerializer(many=True)

    def update(self, instance, validated_data):
        instance.first_name = validated_data.get('first_name', instance.first_name)
        instance.last_name = validated_data.get('last_name', instance.last_name)
        instance.save()
        for data in validated_data.pop('books'):
            book = get_object_or_404(Book, pk=data.get('id'))
            book.title = data.get('title')
            book.isbn = data.get('isbn')
            book.search_url = data.get('search_url')
            book.save()
        return instance

    class Meta:
        model = Author
        fields = ('id', 'first_name', 'last_name', 'books')
```
** base/views.py **
```
# -*- coding:utf-8 -*-
from rest_framework.generics import ListCreateAPIView, RetrieveAPIView, get_object_or_404
from rest_framework.response import Response
from rest_framework import status
from .models import Author, Book
from .serializers import AuthorSerializer, BookSerializer


class AuthorView(ListCreateAPIView):
    """
    Returns a list of all authors.
    """
    queryset = Author.objects.all()
    serializer_class = AuthorSerializer

    def post(self, request, *args, **kwargs):
        data_dict = request.data
        books_data = data_dict.pop('books')
        author, created = Author.objects.get_or_create(**data_dict)
        if created:
            for data in books_data:
                Book.objects.create(author=author, **data)
        else:
            status_code = status.HTTP_406_NOT_ACCEPTABLE
            return Response({'code': status_code, 'msg': '此用戶已存在'}, status=status_code)
        status_code = status.HTTP_200_OK
        return Response({'code': status_code, 'msg': '創建成功'}, status=status_code)


class AuthorInstanceView(RetrieveAPIView):
    """
    Returns a single author.
    Also allows updating and deleting
    """
    serializer_class = AuthorSerializer

    def get_queryset(self):
        return Author.objects.filter(pk=self.kwargs['pk'])

    def get_object(self):
        return get_object_or_404(self.get_queryset(), pk=self.kwargs['pk'])

    def delete(self, request, *args, **kwargs):
        author = self.get_object()
        author.delete()
        # 204(No Content)響應,表示執行成功但是沒有數據,瀏覽器不用刷新頁面也不用導向新的頁面
        status_code = status.HTTP_204_NO_CONTENT
        return Response({'code': status_code, 'msg': '刪除成功'}, status=status_code)

    def put(self, request, *args, **kwargs):
        author = self.get_object()
        serializer = AuthorSerializer(author, data=request.data)
        if serializer.is_valid():
            serializer.update(author, request.data)
            return Response(serializer.data)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class BookView(ListCreateAPIView):
    """
    Returns a list of all books.
    """
    queryset = Book.objects.all()
    serializer_class = BookSerializer
```
** base/urls.py **
```
# -*- coding:utf-8 -*-
from django.conf.urls import url
from .views import AuthorView, AuthorInstanceView, BookView


urlpatterns = [
    url(r'^authors/$', AuthorView.as_view(), name='author-list'),
    url(r'^authors/(?P<pk>\d+)/$', AuthorInstanceView.as_view(), name='author-instance'),
    url(r'^books/$', BookView.as_view(), name='book-list'),

]
```

** 項目 urls.py **
```
from django.conf.urls import include, url
from base import urls as base_urls


urlpatterns = [
    url(r'^api/', include(base_urls)),

]
```

** 最終截圖 **
![](http://upload-images.jianshu.io/upload_images/2733312-274b4ab28c74d7b9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

![](http://upload-images.jianshu.io/upload_images/2733312-2d184ce0ba818c15.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

![](http://upload-images.jianshu.io/upload_images/2733312-867d95a470f621b3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容