Должен ли я использовать GET или POST для запроса с телом в DRF?

Я относительно новичок в веб-разработке и пишу backend для webapp для практических занятий по химическим элементам и соединениям и их формулам в нашей школе. Я использую Django и Django Rest Framework. Я столкнулся с дилеммой, когда не могу решить, использовать ли метод GET или метод POST. Во фронтенде он запрашивает соединения и элементы с сервера с определенными критериями. В этом представлении он получает запрос с телом (критерии), где есть значения requested_count, used_ids (чтобы исключить уже использованные соединения/элементы), requested_groups, requested_elements (чтобы исключить элементы, которые могут быть неизвестны студентам). Каждое значение (кроме count) может быть списком с потенциальными сотнями элементов. Затем он фильтрует базу данных, чтобы вернуть ответ. Я тестировал это много раз, и все работает правильно. Мой единственный вопрос заключается в том, какой метод использовать в этом представлении. Я знаю, что 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")

GET

Метод get используется для получения данных с сервера. Например, список элементов, также обычно списки можно фильтровать по определенному критерию, для этого достаточно метода GET, просто передайте параметры в query-params, например так

example.com/elements?category=random

query-params также можно использовать для сортировки и пагинации.

POST

Чаще всего метод post используется, когда вам нужно отправить определенные данные на сервер в теле запроса формы (если вы используете шаблоны django), создать запись в базе данных и тому подобное.

Поэтому, чтобы решить для себя, какой запрос отправить на сервер, просто задайте себе вопрос: "Что сейчас может сделать клиент?" - Если вы получаете список/один элемент, то вам нужно отправить GET, если клиенту нужно отправить что-то вам на сервер, то POST.

И, наконец, есть такое правило, если вы не знаете, какой запрос отправить, когда вы сомневаетесь, то нужно отправить POST-запрос, например, в случае выхода из системы.

Вернуться на верх