使用Django REST Framework创建REST API

使用Django REST Framework创建REST API

在本教程中,我们将学习一种流行且广泛使用的行业标准数据交换格式——REST API。它是最常用的数据交换技术。我们将解释如何使用Django在Python中创建REST API。在深入探讨这个主题之前,让我们了解REST的概念以及它与传统格式的区别。了解REST将帮助我们更好地理解。让我们简要介绍一下REST API。

什么是REST API

REST是表示状态转移(Representational State Transfer)的首字母缩写,它是一种标准化的提供数据给其他应用程序的方式。换句话说,它用于构建和与Web服务通信。它是跨应用程序传输数据的最佳方式,并且可以被应用程序使用。它规定了Web上的资源以JSON、HTML或XML的形式呈现。有时,API也被用于在其他应用程序中修改数据。

API是应用程序编程接口(Application Programming Interface)的首字母缩写,它定义了不同软件组件之间的交互。Web API决定了请求被发送给组件的具体内容。例如,我们定义一个终点来获取特定分支的学生列表。它还用于定义请求的方式以及它们的预期响应。

以下是一些重要的REST API请求方法。

  • GET :它是从组件中获取数据的最常用方法。根据我们所访问的终点和传递的参数,它从API返回一些数据。
  • POST :它创建新的记录并在数据库中更新新创建的记录。
  • PUT :它将新的记录放在给定的URI上。如果记录存在,则更新记录。如果记录不存在,则创建一个新记录。
  • PATCH :它在给定的URI上接受一个或多个字段。它用于更新一个或多个数据字段。如果记录存在,则更新记录。如果记录不存在,则创建一个新记录。
  • DELETE :它删除给定URI上的记录。

通常,API是一个用于访问数据库的窗口。API负责根据数据库查询获取或更新记录。我们以JSON格式接收静态响应。

REST APIs在软件开发中非常常见,对于开发人员来说,这是一项最受需求和必不可少的技能。API是应用程序之间甚至程序内部进行通信的方式。

许多应用程序依赖于REST APIs。例如,REST API允许前端与后端通信。例如,如果我们使用Django后端部署应用程序,将需要一个API来允许React从数据库中获取信息。

通过实践来进一步了解REST API。现在让我们对Django REST Framework进行简要介绍。

什么是Django Rest Framework

Django Rest Framework(DRF)是在Django之上构建的一个包,用于创建Web API。它提供了Django最丰富的功能,包括对象关系映射(ORM),以一种Pythonic的方式与数据库进行交互。

因此,Python对象无法通过网络发送,因此我们需要将Django模型转换为其他格式(如JSON、XML)以及相反。这个过程被称为序列化,而Django REST框架使其变得非常简单。

DRF允许我们以REST API的形式表示其功能Django应用程序。这样做非常简单。

如果你想深入了解DRF,可以阅读有关如何使用核心Django框架创建REST API的文章。

开始使用Django Rest Framework

由于我们知道Django是一个流行的用于快速开发安全可扩展的Web服务的网络框架。我们的步骤1是创建虚拟环境并在其中安装所有依赖项。让我们创建虚拟环境。

python3 n venv myenv

现在我们需要进入环境中的scripts目录并运行以下命令来激活虚拟环境。

在Mac或Linux上

. myenv/bin/activate

在窗户上

myenv\scripts\activate

现在,通过pip命令安装Django

pip install django

我们准备好创建Django项目和应用程序。

我们已经创建了一个项目和应用程序;它必须在settings.py文件中注册。同时,在应用程序列表中添加 rest_framework ,以让Django知道我们将使用Django REST Framework。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'sample_api',
]

一旦我们注册了应用程序,我们就可以迁移(初始化数据库)并创建一个超级用户来跟踪数据库。

#to initialize the database 
python manage.py migrate 
# to open the prompt
python manage.py createsuperuser

现在,请输入必要的详细信息并创建超级用户。我们已经准备好启动可以接受请求的服务器。

python manage.py runserver

使用DRF在Django中创建一个REST API

我们已经设置好了Django项目;现在,我们可以开始开发领域模型和业务逻辑。

首先,我们创建一个简单的学生模型来表示学生的详细信息。在sample_app/model.py文件中,我们定义了我们的模型。

sample_app/models.py

from django.db import models

# Create your models here.

class Students(models.Model):
    first_name = models.CharField(max_length=200)
    last_name = models.CharField(max_length=200)
    address = models.CharField(max_length=200)
    roll_number = models.IntegerField()
    mobile = models.CharField(max_length=10)

    def __str__(self):
        return self.first_name + " " + self.last_name

我们已经创建了我们的模型,并将这个模型注册到Django中。为了在管理员面板中看到这个模型,我们将在 sample_app/admin.py 中添加以下行。

from django.contrib import admin
from .models import Students

# Register your models here.
admin.site.register(Students)

我们的新模型已经注册。我们需要执行 makemigration 命令以在数据库中反映出Student表。在终端中运行以下命令。

python3 manage.py makemigrations
python3 manage.py migrate

在这里我们可以使用我们的模型。Web应用经常在两端之间传输模型数据。

现在我们要实现DRF中最有用的功能之一, 序列化器。 让我们对序列化器有一个基本的了解。

什么是序列化器?

序列化器用于以JSON格式表示模型数据并将对象实例转换为更易传输的格式。它使得解析来自API的数据的过程变得简单。另一方面,反序列化器将JSON数据转换为我们的模型的对象实例。

我们将在sample_app中创建serializers.py文件,将一个模型对象转换为JSON格式,然后再发送响应。

serializers.py

from rest_framework import serializers
from .models import Students

class StudentSerializer(serializers.ModelSerializer):
    first_name = serializers.CharField(max_length=200, required=True)
    last_name = serializers.CharField(max_length=200, required=True)
    address = serializers.CharField(max_length=200, required=True)
    roll_number = serializers.IntegerField()
    mobile = serializers.CharField(max_length=10, required=True)

    class Meta:
        model = Students
        fields = ('__all__')

serializers.py与Django中的Form类文件非常相似,包括在各个字段上设置验证标志,例如required、max_length和default。在上面的代码中,我们指定了所有字段都是必需的,如果用户没有提供任何字段,就会抛出错误。为了避免错误,我们可以传递默认值。

我们使用了 Modelserializer 类,与Django中的 ModelForm 类相同。也可以使用Serializers类创建序列化器。

from rest_framework import serializers
from .models import Students

class StudentSerializer(serializers.ModelSerializer):
    first_name = serializers.CharField(max_length=200, required=True)
    last_name = serializers.CharField(max_length=200, required=True)
    address = serializers.CharField(max_length=200, required=True)
    roll_number = serializers.IntegerField()
    mobile = serializers.CharField(max_length=10, required=True)

    def create(self, validated_data):
        """
        Create and return a new `Students` instance, given the validated data.
        """
        return Students.objects.create(**validated_data)

    def update(self, instance, validated_data):
        """
        Update and return an existing `Students` instance, given the 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.address = validated_data.get('address', instance.address)
        instance.roll_number = validated_data.get('roll_number', instance.roll_number)
        instance.mobile = validated_data.get('mobile', instance.mobile)

        instance.save()
        return instance

如我们所见,有两种方法 create()update() 方法,在调用 .save() 方法时定义如何创建或修改完全成熟的实例。我们可以使用任一方法创建序列化器。

创建视图

DRF允许我们为API创建基于类和基于函数的视图。我们将创建基于类的视图。

我们将使用APIView类,它是Django View类的子类。我们可以定义get()、post()、patch()和delete()方法来执行CRUD操作。

sample_app/views.py

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Students
from .serializers import StudentSerializer
# Create your views here.

class StudentView(APIView):

    def get(self, request, *args, **kwargs):
        result = Students.objects.all()
        serializers = StudentSerializer(result, many=True)
        return Response({'status': 'success', "students":serializers.data}, status=200)

     def post(self, request):
        serializer = StudentSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({"status": "success", "data": serializer.data}, status=status.HTTP_200_OK)
        else:
            return Response({"status": "error", "data": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)

正如我们所看到的,首先,我们从数据库中获取所有记录,并使用StudentSerializers对它们进行序列化。在post()方法中,我们使用StudentSerializers从request.data创建序列化对象。POST请求将数据发送到服务器中并封装在请求主体中。它用于在数据库中创建一个新记录。如果is_valid()方法返回True,则请求的数据有效,并调用save()方法创建一个新记录。如果返回False,则抛出错误。

响应必须使用要返回的数据进行初始化。这些数据可以是任何类型的Python对象的实例,如bool、str、dict等。

为视图设置端点

首先,我们需要使用以下代码将应用的端点初始化到项目的urls.py中。

config/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('sample_app.urls'))
]

我们可以将 StudentView 类注册为用户的视图。添加它的目的不是为了实现,而是作为请求处理程序。

让我们为 get()post() 方法创建端点。需要在 sample_app 文件夹中创建urls.py文件。我们将在sample_app/urls.py文件中添加以下代码。

sample_app/urls.py

from .views import StudentView
from django.urls import path

urlpattern = [
    path('basic/', StudentView.as_view())
]

在上面的代码中, path() 的第一个参数表示我们的视图应该被访问的子路径,第二个参数是我们在views.py文件中创建的类名。

现在我们可以开始使用我们的API了。

运行服务器

现在,我们运行服务器并使用我们创建的api/basic/端点。

python manage.py runserver

当我们访问本地服务器http://127.0.0.1:8000/时,它将显示我们的端点,我们可以检查我们定义的端点。

http://127.0.0.1:8000/api/basic/是测试get()和post()方法的实际路径。首先我们验证get()方法。

{
    "status": "success",
    "students": [
        {
            "id": 1,
            "first_name": "Rohit",
            "last_name": "Sharma",
            "address": "Agra",
            "roll_number": 101,
            "mobile": "1234567"
        },
        {
            "id": 2,
            "first_name": "Sachin",
            "last_name": "Malhotra",
            "address": "Agra",
            "roll_number": 102,
            "mobile": "7672573"
        },
        {
            "id": 3,
            "first_name": "Arun",
            "last_name": "Tiwari",
            "address": "Jamshedpur",
            "roll_number": 103,
            "mobile": "67654678"
        },
        {
            "id": 4,
            "first_name": "Tusar",
            "last_name": "Srivastava",
            "address": "Varanasi",
            "roll_number": 104,
            "mobile": "87975890"
        }
    ]
}

视图处理 get() 请求,并以JSON格式将可用数据返回给客户端。

让我们测试POST端点。 post() 将从用户那里获取数据,并将其作为新记录添加到数据库中。 DRF将生成自动生成的可浏览API。

使用Django REST Framework创建REST API

我们将传递输入字段,以便我们能够向端点发送一个POST请求。

{
    "status": "success",
    "data": {
        "id": 5,
        "first_name": "Divya",
        "last_name": "Saxsena",
        "address": "Noida",
        "roll_number": 105,
        "mobile": "87975812"
    }
}

新数据已添加到数据库中,这意味着我们的POST方法正常工作。

现在我们获取数据;它将在浏览器中显示全部结果。

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "status": "success",
    "students": [
        {
            "id": 1,
            "first_name": "Rohit",
            "last_name": "Sharma",
            "address": "Agra",
            "roll_number": 101,
            "mobile": "1234567"
        },
        {
            "id": 2,
            "first_name": "Sachin",
            "last_name": "Malhotra",
            "address": "Agra",
            "roll_number": 102,
            "mobile": "7672573"
        },
        {
            "id": 3,
            "first_name": "Arun",
            "last_name": "Tiwari",
            "address": "Jamshedpur",
            "roll_number": 103,
            "mobile": "67654678"
        },
        {
            "id": 4,
            "first_name": "Tusar",
            "last_name": "Srivastava",
            "address": "Varanasi",
            "roll_number": 104,
            "mobile": "87975890"
        },
        {
            "id": 5,
            "first_name": "Divya",
            "last_name": "Saxsena",
            "address": "Noida",
            "roll_number": 105,
            "mobile": "87975812"
        }
    ]
}

请求数据验证

如果我们漏掉任何必需的数据或输入错误的条目会怎么样?例如一个罗尔号的字符串,这个已经被定义为整数。让我们看下面的示例。

输入

{

            "first_name": "Divankar",
            "last_name": "Saxsena",
            "address": "Noida",
            "roll_number": "105",
            "mobile": "87975812"
        }

输出:

{
"status": "error",
"data": {
"roll_number": 
[
"A valid integer is required"
]
}
}

它发出错误,因为我们传递了错误类型的值给 roll_number。 DRF的自动数据验证是一个很好的功能。它会因为我们传递了错误的值类型给 roll_number。 如果我们遗漏了任何字段,它会显示以下错误。

{
    "status": "error",
    "data": {
        "address": [
            "This field is required."
        ]
    }
}

然而,我们也可以通过自定义验证器来定义自定义验证规则。

修改Get请求处理程序

在前面的Get请求示例中,我们获取了表中的所有记录。我们也可以通过将它的id作为参数来检索表中的特定实体。我们获取单个记录并传递给 StudentSerializer() ,这次我们不会传递 many=True ,因为我们只传递单个记录。我们将代码更改如下。

sample_app/views.py

class StudentView(APIView):

    def get(self, request, id):
        result = Students.objects.get(id=id)
        if id:
            serializers = StudentSerializer(result)
            return Response({'success': 'success', "students":serializers.data}, status=200)

        result = Students.objects.all()
        serializers = StudentSerializer(result, many=True)
        return Response({'status': 'success', "students":serializers.data}, status=200)

正如我们所观察到的, StudentSerializer(result, many=True) 已经以JSON格式返回一个对象列表序列化的数据。或者,我们可以通过URL传递id参数- http://127.0.0.1:8000/api/basic/1/。这里我们将1作为id传递,为了处理这个请求,我们需要修改urls.py。我们添加如下的路径。

sample_app/urls.py

from .views import StudentView
from django.urls import path

urlpatterns =    [
    path('basic/', StudentView.as_view()),
    path('basic/<int:id>/', StudentView.as_view())
]

当我们访问 http://127.0.0.1:8000/api/basic/1/ 时,将会显示以下结果。

{
    "success": "success",
    "students": {
        "id": 1,
        "first_name": "Rohit",
        "last_name": "Sharma",
        "address": "Agra",
        "roll_number": 101,
        "mobile": "1234567"
    }
}

我们只得到一个JSON响应,而不是一个对象列表。

更新值的Patch请求处理程序

到目前为止,我们已经实现了获取和添加记录的功能。现在,我们将创建用于更新已经存在于数据库中的记录的端点。我们可以使用针对特定id的POST请求来更新记录。然后,我们检索对象,更新其值,并将其保存在相同的id下,从而保持更改的持久性。

APIView 类提供了 patch() 方法来处理PATCH请求并更新数据。

让我们将views.py文件更新如下。

Class StudentView(APIView):
    def patch(self, request, id):
        result = Students.objects.get(id=id)
        serializer = StudentSerializer(result, data = request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response({"status": "success", "data": serializer.data})
        else:
            return Response({"status": "error", "data": serializer.errors})

我们想要强调的行

serializer = StudentSerializer(result, data=request.data, partial=True)

让我们理解上面的行

  • 获取要更新的给定ID记录。
  • 传递给StudentSerializer以将其转换为JSON。
  • 从请求中接收到的数据。
  • “partial=True”表示这可能不包含我们的Student模型的所有字段。

我们需要传递实际的实例,我们将使用”get()”函数首先检索资源,然后更新它。现在,我们将发送补丁请求到http://127.0.0.1:8000/api/basic/1/,并更新我们的项目。

我们将”last_name”从”Sharma”更改为”Yadav”。

{
        "id": 1,
        "first_name": "Rohit",
        "last_name": "Yadav",
        "address": "Agra",
        "roll_number": 101,
        "mobile": "1234567"
    } 

响应显示更新后的last_name。我们可以通过访问http://127.0.0.1:8000/api/basic/1/update端点进行验证。

{
    "success": "success",
    "students": {
        "id": 1,
        "first_name": "Rohit",
        "last_name": "Yadav",
        "address": "Agra",
        "roll_number": 101,
        "mobile": "1234567"
    }
}

在这里,我们可以看到我们的数据已成功更新。

删除实体 DELETE请求处理程序

用户还想要从数据库中记录一些条目。为此,APIView类提供了delete()方法,该方法按照给定的id删除记录。对于这个目的,我们不需要使用序列化器,因为数据和具体对象之间没有转换。在这里,我们可以使用get_object_or_404()函数,而不是使用Students.objects.get(),如果给定的id不存在,它会自动返回404错误。

让我们理解delete()方法的以下实现。

sample_app/views.py

from django.shortcuts import get_object_or_404

class StudentAPI(APIView):
def delete(self, request, id=None):
result = get_object_or_404(Students, id=id)
result.delete()
return Response({"status": "success", "data": "Record Deleted"})

当我们重新启动服务器时,API浏览器上将显示DELETE按钮。当我们点击DELETE按钮时,它会从数据库中删除该特定id的记录。

使用Django REST Framework创建REST API

删除记录 http://127.0.0.1:8000/api/basic/1/ 后,将显示以下响应。

{
    "status": "success",
    "data": "Record Deleted"
}

当我们访问http://127.0.0.1:8000/api/basic/时,此记录不再存在。

我们使用DRF实现了CRUD API。

CRUD API完整代码

以下是我们在本教程中实现的CRUD操作的完整代码。

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Students
from .serializers import StudentSerializer
from django.shortcuts import get_object_or_404
# Create your views here.

class StudentView(APIView):

    def get(self, request, id):
        result = Students.objects.get(id=id)
        if id:
            serializers = StudentSerializer(result)
            return Response({'success': 'success', "students":serializers.data}, status=200)

        result = Students.objects.all()
        serializers = StudentSerializer(result, many=True)
        return Response({'status': 'success', "students":serializers.data}, status=200)

    def post(self, request):
        serializer = StudentSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({"status": "success", "data": serializer.data}, status=status.HTTP_200_OK)
        else:
            return Response({"status": "error", "data": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)

    def patch(self, request, id):
        result = Students.objects.get(id=id)
        serializer = StudentSerializer(result, data = request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response({"status": "success", "data": serializer.data})
        else:
            return Response({"status": "error", "data": serializer.errors})

    def delete(self, request, id=None):
        result = get_object_or_404(Students, id=id)
        result.delete()
        return Response({"status": "success", "data": "Record Deleted"})

sample_app/urls.py

from .views import StudentView
from django.urls import path

urlpatterns =    [
    path('basic/', StudentView.as_view()),
    path('basic//', StudentView.as_view()),
    path('basic//update/', StudentView.as_view())

结论

本教程详细描述了DRF的概念以及如何在Django中构建一个 RESTful API。在本教程中,我们创建了一个项目并添加 一个示例应用 。我们创建了Student模型和StudentSerializer来处理我们模型的序列化和反序列化。这是一个CRUD API,我们有get()、post()、patch()和delete()这些重要的请求处理程序。通过参考本教程,您可以为练习目的创建购物网站的CRUD API。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程