Django REST API – 带有 DRF 的 CRUD
Django REST Framework 用于非常轻松高效地创建 Web API。这是 Django 框架的一个包装器。在通过 REST 框架创建 API 之前有三个阶段,将模型的数据转换为 JSON/XML 格式(序列化),将此数据渲染到视图,创建用于映射到视图集的 URL。
在本教程中,我们将讨论使用 Django REST API 的 CRUD 操作。它假设您熟悉 Django 基础知识 – Django 教程。
我们要建造什么?
在本教程中,我们将为超市应用程序构建简单的 REST API。这家商店包含各种食品、饮料和家居用品,分为不同的类别。这些类别有子类别,子类别下有项目。每个项目都有一个可以出售的价格。现在我们应该能够使用 DRF API 从我们的数据库中添加、更新、查看和删除此类记录。
假设您在系统中设置并安装了 Django。如果您根本没有任何设置,请参阅以下文章 -
- Django 介绍与安装
- 如何在 Django 中使用 MVT 创建基本项目?
- 如何在 Django 中创建应用程序?
如何安装 Django REST 框架?
要在 Windows、Linux 或任何操作系统上安装 Django REST Framework,需要 pip 包。要检查如何在您的操作系统上安装 pip,请查看 – PIP 安装 – Windows || Linux。
现在,运行一个简单的命令,
pip install djangorestframework
安装 REST 框架后,转到 settings.py,并在 INSTALLED_APPS 的底部添加“ rest_framework ”。
Python3
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
]
Python3
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'api.apps.ApiConfig',
]
Python3
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('api.urls')),
]
Python3
from django.urls import path
urlpatterns = [
]
Python3
from django.db import models
class Item(models.Model):
category = models.CharField(max_length=255)
subcatgeory = models.CharField(max_length=255)
name = models.CharField(max_length=255)
amount = models.PositiveIntegerField()
def __str__(self) -> str:
return self.name
Python3
from django.db.models import fields
from rest_framework import serializers
from .models import Item
class ItemSerializer(serializers.ModelSerializer):
class Meta:
model = Item
fields = ('category', 'subcatgeory', 'name', 'amount')
Python3
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Item
from .serializers import ItemSerializer
@api_view(['GET'])
def ApiOverview(request):
api_urls = {
'all_items': '/',
'Search by Category': '/?category=category_name',
'Search by Subcategory': '/?subcategory=category_name',
'Add': '/create',
'Update': '/update/pk',
'Delete': '/item/pk/delete'
}
return Response(api_urls)
Python3
from django.urls import path
from . import views
urlpatterns = [
path('', views.ApiOverview, name='home')
]
Python3
from rest_framework import serializers
from rest_framework import status
@api_view(['POST'])
def add_items(request):
item = ItemSerializer(data=request.data)
# validating for already existing data
if Item.objects.filter(**request.data).exists():
raise serializers.ValidationError('This data already exists')
if item.is_valid():
item.save()
return Response(item.data)
else:
return Response(status=status.HTTP_404_NOT_FOUND)
Python3
from django.urls import path
from . import views
urlpatterns = [
path('', views.ApiOverview, name='home'),
path('create/', views.add_items, name='add-items'),
]
Python3
@api_view(['GET'])
def view_items(request):
# checking for the parameters from the URL
if request.query_params:
items = Item.objects.filter(**request.query_param.dict())
else:
items = Item.objects.all()
# if there is something in items else raise error
if items:
data = ItemSerializer(items)
return Response(data)
else:
return Response(status=status.HTTP_404_NOT_FOUND)
Python3
from django.urls import path
from . import views
urlpatterns = [
path('', views.ApiOverview, name='home'),
path('create/', views.add_items, name='add-items'),
path('all/', views.view_items, name='view_items'),
]
Python3
@api_view(['POST'])
def update_items(request, pk):
item = Item.objects.get(pk=pk)
data = ItemSerializer(instance=item, data=request.data)
if data.is_valid():
data.save()
return Response(data.data)
else:
return Response(status=status.HTTP_404_NOT_FOUND)
Python3
from django.urls import path
from . import views
urlpatterns = [
path('', views.ApiOverview, name='home'),
path('create/', views.add_items, name='add-items'),
path('all/', views.view_items, name='view_items'),
path('update//', views.update_items, name='update-items'),
]
Python3
@api_view(['DELETE'])
def delete_items(request, pk):
item = get_object_or_404(Item, pk=pk)
item.delete()
return Response(status=status.HTTP_202_ACCEPTED)
Python3
from django.urls import path
from . import views
urlpatterns = [
path('', views.ApiOverview, name='home'),
path('create/', views.add_items, name='add-items'),
path('all/', views.view_items, name='view_items'),
path('update//', views.update_items, name='update-items'),
path('item//delete/', views.delete_items, name='delete-items'),
]
有关更多信息,请参阅我们的文章 Django REST 框架安装。
创建应用
安装 DRF 并将其添加到 settings.py 后,让我们使用以下命令创建一个应用程序 -
python manage.py startapp api
现在已经注册了一个名为 api 的文件夹。
让我们将此应用程序添加到 INSTALLED_APPS 和 urls.py 中。
在settings.py中,
Python3
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'api.apps.ApiConfig',
]
现在,在 urls.py 中添加 api url。在GFG_REST.urls.py 中,
Python3
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('api.urls')),
]
现在让我们在我们的 api 文件夹中创建 urls.py -
在 api/urls.py
Python3
from django.urls import path
urlpatterns = [
]
创建模型
现在让我们创建我们的模型。我们将创建一个项目模型。 API 将使用此模型来执行 CRUD 操作。
Python3
from django.db import models
class Item(models.Model):
category = models.CharField(max_length=255)
subcatgeory = models.CharField(max_length=255)
name = models.CharField(max_length=255)
amount = models.PositiveIntegerField()
def __str__(self) -> str:
return self.name
现在,在我们的应用程序准备好之后,让我们为 Item 类创建序列化程序。
序列化
Django REST Framework 中的序列化器将对象转换为 javascript 和前端框架可以理解的数据类型。序列化器还提供反序列化,允许在首先验证传入数据后将解析的数据转换回复杂类型。最常用的两个主要序列化器是 ModelSerializer 和 HyperLinkedModelSerialzer。
对于本教程,我们将使用 ModelSerializer。如果您想了解有关手动创建序列化程序的更多信息,请参阅以下文章 -
- 序列化器——Django REST 框架
- 序列化程序中的 HyperlinkedModelSerializer – Django REST 框架
模型序列化器
ModelSerializer 是默认序列化器的抽象层,允许快速为 Django 中的模型创建序列化器。它提供了一个快捷方式,让您可以自动创建一个带有对应于模型字段的字段的序列化程序类。 ModelSerializer 类与常规 Serializer 类相同,除了:
- 它将根据模型自动为您生成一组字段。
- 它将自动为序列化程序生成验证器,例如 unique_together 验证器。
- 它包括 .create() 和 .update() 的简单默认实现。
现在让我们在 api 文件夹中创建我们的 serlializers.py 文件并添加以下代码 -
Python3
from django.db.models import fields
from rest_framework import serializers
from .models import Item
class ItemSerializer(serializers.ModelSerializer):
class Meta:
model = Item
fields = ('category', 'subcatgeory', 'name', 'amount')
创建视图
要将数据呈现到前端并处理来自用户的请求,我们需要创建一个视图。在 Django REST Framework 中,我们调用这些视图集,所以让我们在 apis/views.py 中创建一个视图,
Python3
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Item
from .serializers import ItemSerializer
@api_view(['GET'])
def ApiOverview(request):
api_urls = {
'all_items': '/',
'Search by Category': '/?category=category_name',
'Search by Subcategory': '/?subcategory=category_name',
'Add': '/create',
'Update': '/update/pk',
'Delete': '/item/pk/delete'
}
return Response(api_urls)
在上面的代码中, api_view 装饰器获取一个视图应该响应的 HTTP 方法列表。其他方法将响应Method Not Allowed。
现在让我们更新我们的 api/urls.py 文件——
Python3
from django.urls import path
from . import views
urlpatterns = [
path('', views.ApiOverview, name='home')
]
现在让我们取消我们的服务器。运行以下命令 -
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
现在前往 http://127.0.0.1:8000/api/
现在让我们通过我们的 API 来实现我们的 CRUD 操作。
Django Rest 框架 – 创建视图
现在我们的创建视图将使用 POST 方法将数据插入到我们的数据库中。让我们在 views.py 文件中创建我们的 add_items函数。
Python3
from rest_framework import serializers
from rest_framework import status
@api_view(['POST'])
def add_items(request):
item = ItemSerializer(data=request.data)
# validating for already existing data
if Item.objects.filter(**request.data).exists():
raise serializers.ValidationError('This data already exists')
if item.is_valid():
item.save()
return Response(item.data)
else:
return Response(status=status.HTTP_404_NOT_FOUND)
现在让我们更新我们的 urls.py 文件并为我们刚刚创建的创建视图函数添加端点。
Python3
from django.urls import path
from . import views
urlpatterns = [
path('', views.ApiOverview, name='home'),
path('create/', views.add_items, name='add-items'),
]
访问http://127.0.0.1:8000/api/create/
Django Rest 框架 – 列表视图
现在我们的列表视图将使用 GET 方法从我们的数据库中检索数据。让我们在 views.py 文件中创建我们的 view_items函数。这个 view_items函数将显示用户根据类别、子类别或名称查询的所有数据或过滤数据。
在views.py
Python3
@api_view(['GET'])
def view_items(request):
# checking for the parameters from the URL
if request.query_params:
items = Item.objects.filter(**request.query_param.dict())
else:
items = Item.objects.all()
# if there is something in items else raise error
if items:
data = ItemSerializer(items)
return Response(data)
else:
return Response(status=status.HTTP_404_NOT_FOUND)
在 urls.py
Python3
from django.urls import path
from . import views
urlpatterns = [
path('', views.ApiOverview, name='home'),
path('create/', views.add_items, name='add-items'),
path('all/', views.view_items, name='view_items'),
]
现在访问 http://127.0.0.1:8000/api/all/
此视图函数还允许我们按类别或子类别进行过滤。您可以使用以下任一 URL 即 http://127.0.0.1:8000/api/?category=category_name 或 http://127.0.0.1:8000/api/?subcategory=category_name 分别过滤类别和子类别.您还可以使用 http://127.0.0.1:8000/api/all/?name=item_name 搜索特定项目。
如果我们访问 http://127.0.0.1:8000/api/all/?category=food 我们的搜索结果将缩小到 -
Django Rest 框架 – 更新视图
现在对于我们的更新视图函数,我们将使用 POST 方法。让我们在 views.py 文件中创建我们的 update_items函数。此视图函数将更新数据库中的特定项目。它将在主键的帮助下过滤项目。
在views.py
Python3
@api_view(['POST'])
def update_items(request, pk):
item = Item.objects.get(pk=pk)
data = ItemSerializer(instance=item, data=request.data)
if data.is_valid():
data.save()
return Response(data.data)
else:
return Response(status=status.HTTP_404_NOT_FOUND)
在 urls.py
Python3
from django.urls import path
from . import views
urlpatterns = [
path('', views.ApiOverview, name='home'),
path('create/', views.add_items, name='add-items'),
path('all/', views.view_items, name='view_items'),
path('update//', views.update_items, name='update-items'),
]
现在前往 http://127.0.0.1:8000/api/all/?name=potato
Django Rest Framework – 删除视图
对于我们的删除视图函数,我们将使用 DELETE 方法。让我们在 views.py 文件中创建我们的 delete_items函数。此视图函数将从数据库中删除特定项目。
在views.py
Python3
@api_view(['DELETE'])
def delete_items(request, pk):
item = get_object_or_404(Item, pk=pk)
item.delete()
return Response(status=status.HTTP_202_ACCEPTED)
在 urls.py
Python3
from django.urls import path
from . import views
urlpatterns = [
path('', views.ApiOverview, name='home'),
path('create/', views.add_items, name='add-items'),
path('all/', views.view_items, name='view_items'),
path('update//', views.update_items, name='update-items'),
path('item//delete/', views.delete_items, name='delete-items'),
]
现在访问 http://127.0.0.1:8000/api/item/pk/delete/。请参阅下面的 GIF 以获得更好的理解。