- В этой статье мы начнем с базового API, созданного с помощью наборов представлений, маршрутизатора, ModelSerializer, а затем настроим его.
- Рекомендуемый раздел для чтенияучебник для остальных фреймворков
- Версия:
- Django==2.0.1
- djangorestframework==3.7.7
- адрес гитхаба
разное:
- Напишите RESTful API с помощью Django REST framework (3. Добавьте модуль комментариев)
- Напишите RESTful API с помощью Django REST framework (2. Настройте наборы представлений и сериализатор моделей)
Создайте API для ведения блога с помощью наборов представлений, маршрутизатора, ModelSerializer.
Создайте модель блога
В статье должны быть:
- заглавие
- основная часть статьи
- время выпуска
- Этикетка
- автор
Связь между тегами и статьями должна быть «многие ко многим» (статья может иметь несколько тегов, а тег может быть связан с несколькими статьями).
Связь между авторами и статьями должна быть «один ко многим» (у автора может быть несколько статей, а у статьи только один автор).
Требуется три модели: Статья (Пост), Тег (Тэг), Автор (Пользователь)
class Post(models.Model):
"""
title:标题
body:主体
pub_time:发布时间
tag:标签,多对多
author:作者,一对多
"""
title = models.CharField(max_length=100, blank=True, default='')
body = models.TextField()
pub_time = models.DateTimeField(auto_now_add=True)
tags = models.ManyToManyField('Tag', related_name='posts', blank=True)
author = models.ForeignKey('auth.User', related_name='posts', on_delete=models.CASCADE)
class Meta:
ordering = ('-pub_time',)
class Tag(models.Model):
name = models.CharField(max_length=50)
Модель автора использует модель пользователя Django для упрощения аутентификации и управления разрешениями.
Сериализатор сборки
Сериализатор — очень важная часть остального фреймворка.
В Django это обычно взаимодействие между Моделью и Представлением, Представление обрабатывает запрос, передает данные в Модель, а Представление отображает данные, полученные из Модели.
В остальном сериализатор эквивалентен промежуточной обработке между моделью и представлением: он сериализует данные, полученные от модели, и передает их представлению, а также десериализует данные, полученные от представления, и передает их модели.
Создайте новый файл serializer.py, который использует HyperlinkedModelSerializer для создания сериализатора:
from django.contrib.auth.models import User
from restAPI.models import Post, Tag
class PostSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Post
fields = ('url', 'id', 'title', 'pub_time', 'author', 'body', 'tags')
class TagSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Tag
fields = ('url', 'id', 'name', 'posts')
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'id', 'username', 'posts')
HyperlinkedModelSerializer будет генерировать URL-адреса для реляционных данных по умолчанию, поэтому нет необходимости объявлять «сообщения» в полях в теге и пользователе.
Представления сборки
Чтобы установить разрешения, создайте новый файл permission.py:
from rest_framework import permissions
class IsAuthorOrReadOnly(permissions.BasePermission):
"""
只允许作者修改但允许所有人读的权限设置
"""
def has_object_permission(self, request, view, obj):
# 所有用户都允许读取,所以安全的http方法会直接放行
# SAFE_METHODS = ('GET', 'HEAD', 'OPTIONS')
if request.method in permissions.SAFE_METHODS:
return True
# 写入权限需要作者本人
return obj.author == request.user
Создание представлений с наборами представлений:
from rest_framework import viewsets, permissions, mixins
from django.contrib.auth.models import User
from restAPI.models import Post, Tag
from restAPI.serializers import PostSerializer, TagSerializer, UserSerializer
from restAPI.permissions import IsAuthorOrReadOnly
class PostViewSet(viewsets.ModelViewSet):
"""
处理 /api/posts/ GET POST , 处理 /api/post/<pk>/ GET PUT PATCH DELETE
"""
queryset = Post.objects.all()
serializer_class = PostSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsAuthorOrReadOnly)
def perform_create(self, serializer):
"""
重写 perform_create
user 信息不在 request.data 中, 在保存时加入 user 信息
"""
serializer.save(author=self.request.user)
class TagViewSet(mixins.CreateModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
"""
处理 /api/tags/ GET POST, 处理 /api/tags/<pk>/ GET
"""
queryset = Tag.objects.all()
serializer_class = TagSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class UserViewSet(viewsets.ReadOnlyModelViewSet):
"""
处理 /api/users/ GET, 处理 /api/users/<pk>/ GET
"""
queryset = User.objects.all()
serializer_class = UserSerializer
ModelViewSet передает данные сериализатору через get_serializer(data=request.data) в create(), но информация о пользователе находится не в request.data, а в качестве атрибута запроса, поэтому добавьте пользователя при сохранении, переопределив Perform_create()
строить URL
Поскольку использование ViewSets All Router создает URL-адреса, очень просто: URL-адреса проекта:
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('restAPI.urls'))
]
app urls:
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from restAPI.views import PostViewSet, TagViewSet, UserViewSet
router = DefaultRouter()
router.register(r'posts', PostViewSet)
router.register(r'tags', TagViewSet)
router.register(r'users', UserViewSet)
urlpatterns = [
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls')),
]
include(router.urls) поможет нам сгенерировать его напрямую
- /api/posts/
- /api/posts/<pk>/
- /api/users/
- /api/users/<pk>/
- /api/tags/
- /api/tags/<pk>/
конец
На данный момент базовый API создан, но есть еще некоторые проблемы:
- "Тело" в последовательности полученной GET /api/posts/ это вся информация. Когда мы получаем список постов, нам не нужна такая полная информация, что приводит к трате трафика. В теге author только ссылки , а информации слишком мало.
- GET /api/tags/ публикует только ссылки, слишком мало информации
Они будут рассмотрены в следующей статье
разное: