Джанго: Общие вопросы о представлениях API

Я работаю над проектом, и у меня есть фронтенд на React, который делает несколько базовых CRUD-вызовов axios на сервер Django.

Я пытаюсь найти лучший способ администрирования моих представлений Django для получения и обработки этих запросов. Я понимаю, что это очень сильно зависит от того, как должно функционировать мое приложение. Но в данный момент я просто пытаюсь создать простые представления (которые соединяют несколько моделей данных вместе и возвращают)

Вот этот подход в действии:

class Hero(models.Model):
    character = models.ForeignKey(
        Card, on_delete=models.CASCADE, related_name="class_id", null=True
    )
    weapon = models.ForeignKey(
        Card, on_delete=models.CASCADE, related_name="weapon_id", null=True
    )
    player = models.OneToOneField(Player, on_delete=models.PROTECT, null=True)

class Game(models.Model):
    hero1 = models.ForeignKey(
        Hero, on_delete=models.PROTECT, related_name="hero1_id", null=True
    )
    hero2 = models.ForeignKey(
        Hero, on_delete=models.PROTECT, related_name="hero2_id", null=True
    )
    hero3 = models.ForeignKey(
        Hero, on_delete=models.PROTECT, related_name="hero3_id", null=True
    )
    hero4 = models.ForeignKey(
        Hero, on_delete=models.PROTECT, related_name="hero4_id", null=True
    )

и затем я бы написал представление в таком виде,

class GameHeroView(APIView):
    serializer_class = HeroSerializer

    def get(self, request, id=0):
        game_id = request.query_params.get("id")
        if game_id is None:
            game_id = id

        # Create an empty list for serialized data
        serialized_data = []

        sql = (
            " \
              SELECT gh.* \
                FROM gauntlet_game gg, \
                     gauntlet_hero gh \
              WHERE gg.id = "
            + str(game_id)
            + " \
                AND (gg.hero1_id = gh.id \
                    OR gg.hero2_id = gh.id \
                    OR gg.hero3_id = gh.id \
                    OR gg.hero4_id = gh.id)"
        )

        heros = Hero.objects.raw(sql)
        serialized_data = HeroSerializer(heros, many=True).data

        # Create the custom response object
        response_data = {
            "count": len(serialized_data),
            "next": None,  # You can set this to the next page URL if pagination is used
            "previous": None,  # You can set this to the previous page URL if pagination is used
            "results": serialized_data,
        }
        return Response(response_data)

Например, я хочу получить всех героев для каждой записи игры (которая уже существует). В настоящее время я использую следующий подход:

  1. создайте новый класс представления специально для каждого случая,
  2. определите методы get, post, put и т.д. для каждого вида.

Так, например, если мне нужно обновить всех героев для одного game_id, я могу реализовать метод put в этом классе. Кроме этих методов, не должно существовать никаких других методов, и должен быть создан только новый класс.

Вот мои вопросы:

  1. Является ли такой подход жизнеспособным или я слишком ограничиваю себя.
  2. В инструментах django, Есть ли какой-нибудь конкретный инструмент, чтобы посмотреть, что запрашивается? У меня много ошибок, иногда с неправильным типом метода или проблемами с установкой параметров запроса, и это может стать трудным для отладки.

Любые учебники/ссылки будут приняты с благодарностью.

Я бы рекомендовал вам взглянуть на django rest framework model view sets

Это очень хорошо подходит для вашего случая. Вы в основном хотите выполнять грубые операции над моделью, этот ModelViewSet позволит вам перечислять, создавать, удалять, обновлять, получать (single). В случае, если вам, например, нужен только список и создание, вы можете просто удалить миксины соответственно.

class ModelViewSet(mixins.CreateModelMixin,
               mixins.RetrieveModelMixin,
               mixins.UpdateModelMixin,
               mixins.DestroyModelMixin,
               mixins.ListModelMixin,
               GenericViewSet):

Затем, если вы хотите сделать определенный фильтр в вашем ViewSet, имеет смысл включить пакет django-filter, который позволит вам поместить filterset_fields, см. ниже:

class CalculationViewSet(viewsets.ModelViewSet):
    queryset = Calculation.objects.all()
    serializer_class = CalculationSerializer
    filterset_fields = {
        'project': ["exact"],
    }

В этом примере я позволяю отфильтровать набор запросов по url следующим образом:

localhost:8000/calculations/?project=3

В результате будут получены только те вычисления, которые имеют project_id 3.

Обратите внимание, что в вашей конечной точке вы также создаете риск безопасности для SQL-инъекций. Вы не проводите валидацию для game_id, а это значит, что хакеры могут вставить вредоносный SQL-запрос, который будет иметь больше доступа, чем хочет предоставить ваше приложение.

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