Джанго: Общие вопросы о представлениях 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)
Например, я хочу получить всех героев для каждой записи игры (которая уже существует). В настоящее время я использую следующий подход:
- создайте новый класс представления специально для каждого случая,
- определите методы get, post, put и т.д. для каждого вида.
Так, например, если мне нужно обновить всех героев для одного game_id, я могу реализовать метод put в этом классе. Кроме этих методов, не должно существовать никаких других методов, и должен быть создан только новый класс.
Вот мои вопросы:
- Является ли такой подход жизнеспособным или я слишком ограничиваю себя.
- В инструментах 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-запрос, который будет иметь больше доступа, чем хочет предоставить ваше приложение.