Платформа DRF предоставляет множество общих базовых классов представлений и классов расширения для упрощения написания представлений.
APIView: базовый класс всех представлений, предоставляемых DRF, наследует и расширяет View и имеет такие функции, как аутентификация личности, проверка разрешений и управление потоком.
E:\workspace\django-project\day2\django_drf>python manage.py startapp myapp
from rest_framework.views import APIView
from rest_framework.response import Response
class UserAPIView(APIView):
def get(self,request):
data = {'result': 'get'}
return Response(data)
def post(self,request):
data = {'result': 'post'}
return Response(data)
def put(self,request):
data = {'result': 'put'}
return Response(data)
def delete(self,request):
data = {'result': 'delete'}
return Response(data)
from django.urls import re_path
from myapp import views
urlpatterns = [
re_path('^users1/$', views.UserAPIView.as_view())
]
Объект запроса, передаваемый в представление DRF, больше не является объектом Django HttpRequest по умолчанию, а является объектом класса Request, основанным на расширении класса HttpRequest.
Данные объекта Request автоматически анализируются в едином формате данных на основе данных, отправленных внешним интерфейсом.
DRF предоставляет класс ответа Response, и данные ответа будут автоматически преобразованы в формат данных JSON, соответствующий интерфейсу.
Импорт:
from rest_framework.response import Response
Формат:
Response(data, status=None, template_name=None, headers=None, content_type=None)
Как использовать:
return Reponse(data=data, status=status.HTTP_404_NOT_FOUND)
Чтобы облегчить настройку кодов состояния, модуль rest_framework.status предоставляет все коды состояния HTTP. Ниже приведены некоторые часто используемые коды:
HTTP_200_OK: запрос успешен
HTTP_301_MOVED_PERMANENTLY: постоянное перенаправление
HTTP_302_FOUND: временное перенаправление
HTTP_304_NOT_MODIFIED: запрошенный ресурс не был изменен.
HTTP_403_FORBIDDEN: нет разрешения на доступ
HTTP_404_NOT_FOUND: страница не найдена
HTTP_500_INTERNAL_SERVER_ERROR: внутренняя ошибка сервера
HTTP_502_BAD_GATEWAY: неверный шлюз
HTTP_503_SERVICE_UNAVAILABLE: сервер недоступен.
HTTP_504_GATEWAY_TIMEOUT: тайм-аут шлюза
from django.db import models
class User(models.Model):
name = models.CharField(max_length=32)
city = models.CharField(max_length=64)
sex = models.CharField(max_length=8)
age = models.IntegerField()
from myapp.models import User
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
E:\workspace\django-project\day2\django_drf>python manage.py makemigrations
E:\workspace\django-project\day2\django_drf>python manage.py migrate
E:\workspace\django-project\day2\django_drf>python manage.py shell
In [1]: from myapp.models import User
In [2]: User.objects.create(name="Чжан Сан",city="Пекин",sex="Мужской",возраст=29)
In [3]: User.objects.create(name="Ли Си",city="Шанхай",sex="женский",возраст=19)
In [4]: User.objects.create(name="Ашан",city="Город Гуанчжоу",sex="Женский",возраст=23)
In [5]: User.objects.create(name="Ах Яо",city="Город Шэньчжэнь",секс="мужской",age=21)
from myapp.models import User
from rest_framework.generics import GenericAPIView
from .serializers import UserSerializer
from rest_framework.response import Response
class UserGenericAPIViews(GenericAPIView):
queryset = User.objects.all() #Указываем данные для операции
serializer_class = UserSerializer #Указать сериализатор
lookup_field = 'id'
def get(self,request, id=None):
if id:
user_obj = self.get_object() #Вызов указанных данных из метода класса, идентификатор передавать не нужно
user_ser = self.get_serializer(user_obj)
else:
quertset = self.get_queryset() # Вызов всех данных из метода класса
user_ser = self.get_serializer(quertset, many=True) #Вызов сериализатора из метода класса
result = {"code": 200, "msg": "success", "data": user_ser.data}
return Response(result)
def post(self,request):
user_ser = self.get_serializer(data=request.data)
user_ser.is_valid(raise_exception=True)
user_ser.save()
result = {"code": 200, "msg": "create success"}
return Response(result)
def put(self,request,id=None):
user_obj = self.get_object()
user_ser = self.get_serializer(instance=user_obj,data=request.data)
user_ser.is_valid(raise_exception=True)
result = {"code": 200, "msg": "update success"}
return Response(result)
def delete(self,request,id=None):
user_obj = self.get_object()
user_obj.delete()
result = {"code": 200, "msg": "delete success"}
return Response(result)
from django.urls import re_path
from myapp import views
urlpatterns = [
re_path('^users1/$', views.UserAPIView.as_view()),
re_path('^users2/$',views.UserGenericAPIViews.as_view()), #Получаем все данные и создаем
re_path('^users2/(?P<id>\d+)/$',views.UserGenericAPIViews.as_view()), #Получаем один фрагмент данных и его обновления и удаляем его
]
http://127.0.0.1:8000/myapp/users2/ #list,почта
http://127.0.0.1:8000/myapp/users2/5/ #Обновляем указанные данные идентификатора,удалить,Проверять
GenericAPIView выполнил множество функций.,Но будет проблема,Для получения списка всех пользователей и одного пользователя необходимо определить два представления и URL-маршруты соответственно.,Эту проблему можно очень хорошо решить с помощью ViewSet.,и понялАвтоматическое отображение маршрута
。
ViewSet больше не реализует методы get(), post() и другие, но реализует следующие действия метода запроса:
list(): Получить все данные
извлечь(): получить отдельные данные
create(): Создать данные
update(): обновить данные
destory():удалитьданные
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
from myapp.models import User
from .serializers import UserSerializer
class UserViewSet(ViewSet):
lookup_field = 'id' #Это нужно использовать при автоматической регистрации маршрутов
def list(self,request):
user_obj = User.objects.all()
user_ser = UserSerializer(user_obj, many=True)
result = {"code": 200, "msg": "success", "data": user_ser.data}
return Response(result)
def retrieve(self,request,id=None):
user_obj = User.objects.get(id=id)
user_ser = UserSerializer(user_obj)
result = {"code": 200, "msg": "success", "data": user_ser.data}
return Response(result)
def update(self,request,id=None):
user_obj = User.objects.get(id=id)
user_ser = UserSerializer(instance=user_obj,data=request.data)
user_ser.is_valid(raise_exception=True)
user_ser.save()
result = {"code": 200, "msg": "update success"}
return Response(result)
def create(self,request):
user_ser = UserSerializer(data=request.data)
user_ser.is_valid(raise_exception=True)
user_ser.save()
result = {"code": 200, "msg": "create success"}
return Response(result)
def destory(self,request,id=None):
user_obj = User.objects.get(id=id)
user_obj.delete()
result = {"code": 200, "msg": "delete success"}
return Response(result)
from django.urls import re_path
from myapp import views
urlpatterns = [
re_path('^users1/$', views.UserAPIView.as_view()),
re_path('^users2/$',views.UserGenericAPIViews.as_view()), #Получаем все данные и создаем
re_path('^users2/(?P<id>\d+)/$',views.UserGenericAPIViews.as_view()), #Получаем один фрагмент данных и его обновления и удаляем его
re_path('^users3/$',views.UserViewSet.as_view({'get': 'list','post': 'create'})), #Получаем все данные и создаем
re_path('^users3/(?P<id>\d+)/$',views.UserViewSet.as_view({'get': 'retrieve','put': 'update','delete': 'destory'})), #Получаем один фрагмент данных и его обновления и удаляем его
]
http://127.0.0.1:8000/myapp/users3/ #list,почта
http://127.0.0.1:8000/myapp/users3/5/ #Обновляем указанные данные идентификатора,удалить,Проверять
from django.urls import re_path,include
from myapp import views
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('user4',views.UserViewSet,'user4')
router.register('user5',views.UserViewSet,'user5') #Зарегистрируйтесь еще раз
urlpatterns = [
re_path('^users1/$', views.UserAPIView.as_view()),
re_path('^users2/$',views.UserGenericAPIViews.as_view()), #Получаем все данные и создаем
re_path('^users2/(?P<id>\d+)/$',views.UserGenericAPIViews.as_view()), #Получаем один фрагмент данных и его обновления и удаляем его
re_path('^users3/$',views.UserViewSet.as_view({'get': 'list','post': 'create'})), #Получаем все данные и создаем
re_path('^users3/(?P<id>\d+)/$',views.UserViewSet.as_view({'get': 'retrieve','put': 'update','delete': 'destory'})), #Получаем один фрагмент данных и его обновления и удаляем его
re_path('^api/',include(router.urls))
]
http://127.0.0.1:8000/myapp/api/ #Просмотр зарегистрированного списка URL-адресов
http://127.0.0.1:8000/myapp/api/user4/ #list,почта
http://127.0.0.1:8000/myapp/api/user4/2/ #Обновляем указанные данные идентификатора,удалить,Проверять
Поскольку ModelViewSet имеет более высокий уровень абстракции, он может реализовывать функции автоматического добавления, удаления, изменения и запроса. Что касается дополнений и изменений, он не может удовлетворить потребности во многих сценариях, поэтому соответствующие методы необходимо переписать.
from rest_framework.viewsets import ModelViewSet
class UserModelViewSet(ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
from django.urls import re_path,include
from myapp import views
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('user4',views.UserViewSet,'user4')
router.register('user5',views.UserViewSet,'user5')
router.register('user6',views.UserModelViewSet,'user6') #Внедрить ModelViewSet
urlpatterns = [
re_path('^users1/$', views.UserAPIView.as_view()),
re_path('^users2/$',views.UserGenericAPIViews.as_view()), #Получаем все данные и создаем
re_path('^users2/(?P<id>\d+)/$',views.UserGenericAPIViews.as_view()), #Получаем один фрагмент данных и его обновления и удаляем его
re_path('^users3/$',views.UserViewSet.as_view({'get': 'list','post': 'create'})), #Получаем все данные и создаем
re_path('^users3/(?P<id>\d+)/$',views.UserViewSet.as_view({'get': 'retrieve','put': 'update','delete': 'destory'})), #Получаем один фрагмент данных и его обновления и удаляем его
re_path('^api/',include(router.urls))
]
http://127.0.0.1:8000/myapp/api/ #Просмотр зарегистрированного списка URL-адресов
http://127.0.0.1:8000/myapp/api/user6/ #list,create
http://127.0.0.1:8000/myapp/api/user6/ #update, delete, retrieve
HTTP — это протокол без сохранения состояния. Каждое посещение является новым. Раньше он использовался в основном для просмотра веб-страниц. С развитием времени, например, с появлением веб-сайтов онлайн-покупок, мы столкнулись с записью тех, кто входит в систему. систему и кто помещает товары в свои корзины. То есть всех надо различать, поэтому есть имя пользователя для их идентификации, но вам приходится входить в систему каждый раз, когда вы посещаете страницу, что очень хлопотно, поэтому происходит сохранение сеанса. Cookie+Session — это технология сохранения сеанса.
Cookie+Session обычно более распространен, когда браузер выступает в качестве клиента. С популяризацией модели разработки разделения внешнего и внутреннего интерфейса в нем будут задействованы несколько терминалов (ПК, приложение, планшет), особенно мобильный терминал. не поддерживает файлы cookie, а файлы cookie не поддерживают междоменный доступ, поэтому, учитывая эти ограничения, токен постепенно становится основным.
Как и обычные токены, они являются токенами для доступа к ресурсам. Разница в том, что обычные серверы токенов должны запрашивать базу данных для проверки при проверке информации токена. JWT не нужно запрашивать базу данных для проверки информации токена, и ему нужно только использовать проверку ключа. на стороне сервера. Как и обычные токены, они являются токенами для доступа к ресурсам. Разница в том, что обычные серверы токенов должны запрашивать базу данных для проверки при проверке информации токена. JWT не нужно запрашивать базу данных для проверки информации токена, и ему нужно только использовать проверку ключа. на стороне сервера.
В настоящее время доступ к DRF возможен произвольно и без каких-либо ограничений, что не соответствует стандартам производственной среды. Поэтому следующим шагом является изучение аутентификации для реализации контроля доступа.
Поскольку Django по умолчанию предоставляет механизм хранения сеансов, вы можете напрямую войти во встроенную систему управления для проверки. Когда вы входите в систему управления, у вас есть разрешение на доступ к ней.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
}
from rest_framework.viewsets import ModelViewSet
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
class UserModelViewSet(ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
#Сертификация&Конфигурация разрешений
authentication_classes = [SessionAuthentication]
permission_classes = [IsAuthenticated]
REST_FRAMEWORK = {
#Сертификация
'DEFAULT_AUTHENTICATION_CLASSES': [
#'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
],
#Разрешения
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
}
E:\workspace\django-project\day2\django_drf>python manage.py makemigrations
E:\workspace\django-project\day2\django_drf>python manage.py migrate
from django.contrib import admin
from django.urls import path,include,re_path
from rest_framework.authtoken import views
urlpatterns = [
path('admin/', admin.site.urls),
path('myapp/',include("myapp.urls")),
re_path('^auth_token/$', views.obtain_auth_token)
]
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.response import Response
from rest_framework.authtoken.models import Token
class CustomAuthToken(ObtainAuthToken):
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
return Response({'token': token.key, 'username': user.username})
from django.contrib import admin
from django.urls import path,include,re_path
# from rest_framework.authtoken import views
from myapp.utils.auth_token import CustomAuthToken
urlpatterns = [
path('admin/', admin.site.urls),
path('myapp/',include("myapp.urls")),
re_path('^auth_token/$', CustomAuthToken.as_view())
]
Частота доступа к интерфейсу может быть ограничена, чтобы снизить нагрузку на сервер.
Сценарии применения: голосование, количество покупок и т. д.
REST_FRAMEWORK = {
#Сертификация
'DEFAULT_AUTHENTICATION_CLASSES': [
#'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
],
#Разрешения
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
#Ограничение тока
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '10/minute',
'user': '10/minute'
}
}
pip3 install django-filter
REST_FRAMEWORK = {
#Сертификация
# 'DEFAULT_AUTHENTICATION_CLASSES': [
# 'rest_framework.authentication.SessionAuthentication',
# 'rest_framework.authentication.TokenAuthentication',
# ],
#Разрешения
# 'DEFAULT_PERMISSION_CLASSES': [
# 'rest_framework.permissions.IsAuthenticated',
# ],
#Ограничение тока
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '10/minute',
'user': '10/minute'
},
#фильтр Конфигурация 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
}
from rest_framework.viewsets import ModelViewSet
class UserModelViewSet(ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
#фильтр
filter_fields = ('sex',)
DRF предоставляет инструмент фильтра, который помогает нам быстро осуществлять поиск и сортировку.
from rest_framework.viewsets import ModelViewSet
from rest_framework import filters
class UserModelViewSet(ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
#фильтр
filter_fields = ('sex',)
#поиск&сортировать
filter_backends = [filters.SearchFilter,filters.OrderingFilter]
search_fields = ('name',)
order_fields = ('age',)
Пагинация — необходимая функция для таблиц данных.,Может быть реализован на переднем конце,Это также может быть реализовано на бэкэнде,Чтобы избежать слишком большого размера данных ответа,вызывая давление на переднюю часть,Обычно реализуется на бэкэнде.
REST_FRAMEWORK = {
#Ограничение тока
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '10/minute',
'user': '10/minute'
},#фильтр Конфигурация 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
#globalПагинация
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 3 #Три фрагмента данных на странице
}
from rest_framework.pagination import PageNumberPagination
from collections import OrderedDict
from rest_framework.response import Response
class CustomPagination(PageNumberPagination):
page_size = 10 #Сколько фрагментов данных отображается на каждой странице?
page_query_param = 'page_num' #Запросить, какая страница данных
page_size_query_param = 'page_size' #Сколько элементов отображается на странице?
max_page_size = 50 #Максимальное количество явных записей на странице: 50
def get_paginated_response(self, data):
return Response(OrderedDict([
('total_num', self.page.paginator.count),
('next_page', self.get_next_link()),
('msg', 'success'),
('code',200),
('previous_page', self.get_previous_link()),
('data', data)
]))
REST_FRAMEWORK = {
#Ограничение тока
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '10/minute',
'user': '10/minute'
},#фильтр Конфигурация 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
# Пользовательская пагинация
'DEFAULT_PAGINATION_CLASS': 'myapp.utils.my_pagination.CustomPagination'
}
Из-за отсутствия опыта разработки проектов или стремления выйти в онлайн требования постоянно меняются, а интерфейсы, определенные на этапе проектирования проекта, изменились до неузнаваемости. Это создает определенные трудности для фронтенд-разработчиков. Как улучшить. эта проблема?
pip3 install django-rest-swagger
REST_FRAMEWORK = {
#Ограничение тока
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '10/minute',
'user': '10/minute'
},#фильтр Конфигурация 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
# Пользовательская пагинация
'DEFAULT_PAGINATION_CLASS': 'myapp.utils.my_pagination.CustomPagination',
#Документ интерфейса
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
}
D:\devTools\python3\lib\site-packages\rest_framework_swagger\templates\rest_framework_swagger\index.html
Измените вторую строку staticfiles в index.html на static, чтобы решить проблему.