在DRF中,带有请求体的应该使用GET还是POST?

1 投票
1 回答
38 浏览
提问于 2025-04-12 05:42

我刚开始接触网页开发,现在正在为学校写一个后端程序,主要是练习化学元素、化合物和它们的公式。我使用的是Django和Django Rest Framework。在这个过程中,我遇到了一个困扰我的问题:我不知道该用GET方法还是POST方法。在前端,我会根据特定的条件向服务器请求化合物和元素。在这个请求中,会包含一些信息,比如请求的数量、已经使用过的ID(为了排除那些已经用过的化合物/元素)、请求的组和请求的元素(为了排除那些学生可能不认识的元素)。除了数量以外,每个值都可能是一个包含几百个项目的列表。然后,系统会过滤数据库,返回相应的结果。我已经测试过很多次,运行得很好。我的唯一疑问是,在这个请求中应该使用哪种方法。我知道POST方法是用来修改数据库的,而GET方法是用来从数据库获取数据的。根据这个逻辑,我应该使用GET方法。但我想在请求中发送一些内容,而这通常是POST方法的作用。你有什么建议吗?谢谢

以下是视图代码:

class RequestCompoundsView(views.APIView):
serializer_class = RequestCompoundsSerializer

def get(self, request):
    serializer = self.serializer_class(data=request.data)

    if serializer.is_valid():
        # Get the request data from serializer
        requested_count = serializer.validated_data.get("count", 10)
        used_ids = serializer.validated_data.get("used_ids", [])
        requested_groups = serializer.validated_data.get("groups", [])
        requested_elements = serializer.validated_data.get("elements", [])

        # Find the elements and groups objects
        groups, elements = find_requested_groups_elements(
            requested_groups, requested_elements
        )

        # Check if the group and element names are correct
        if groups.count() == 0:
            context = {"error": "invalid group name"}
            return Response(context, status=status.HTTP_400_BAD_REQUEST)

        if elements.count() == 0:
            context = {"error": "invalid element name"}
            return Response(context, status=status.HTTP_400_BAD_REQUEST)

        # Make a query and filter it out the database
        query = ~Q(id__in=used_ids) & Q(group__in=groups) & Q(elements__in=elements)
        samples = (
            Compound.objects.filter(query)
            .order_by("?")[:requested_count]
            .select_related("group")
        )
        count = Compound.objects.filter(query).count()

        # Check if the wanted conditions are correct
        if count == 0:
            context = {"error": "query returned no results"}
            return Response(context, status=status.HTTP_204_NO_CONTENT)

        # Return the results
        serializer = SendCompoundsSerializer(samples, many=True)
        context = {"data": serializer.data, "count": count}
        return Response(context, status=status.HTTP_200_OK)

    # If there is a problem, return bad request
    else:
        print(serializer.errors)
        context = {"error": "invalid request data"}
        return Response(context, status=status.HTTP_400_BAD_REQUEST)

以下是序列化器:

# Serializer for the incomming requests
class RequestCompoundsSerializer(serializers.Serializer):
    used_ids = serializers.ListField(child=serializers.IntegerField())
    groups = serializers.ListField(child=serializers.CharField())
    elements = serializers.ListField(child=serializers.CharField())
    count = serializers.IntegerField(max_value=100, min_value=1)

    class Meta:
        fields = ("used_ids", "groups", "elements", "count")


# Response of the server for the frontend
class SendCompoundsSerializer(serializers.ModelSerializer):

    class Meta:
        model = Compound
        fields = ("id", "formula", "name")

1 个回答

0

GET

GET方法是用来从服务器获取数据的。比如说,你想要获取一个元素的列表,通常这些列表可以根据某些条件进行筛选。使用GET方法就足够了,只需要把参数放到查询参数中,比如这样:

example.com/elements?category=random

查询参数也可以用来进行排序和分页。

POST

POST方法通常是在你需要把某些数据发送到服务器时使用,比如在表单请求的主体中(如果你使用的是django模板),或者是创建数据库中的记录等等。

所以,想要决定发送什么请求给服务器,可以问自己一个问题:“客户端现在能做什么?”如果你是要获取一个列表或单个元素,那就用GET;如果客户端需要发送一些东西到服务器,那就用POST。

最后,有一个小规则,如果你不确定该发送什么请求,或者有疑问的时候,最好发送POST请求,比如在注销的时候。

撰写回答