Мы хотим дать возможность находить во всех таблицах записи по полям в связанных таблицах. На самом деле мы хотели бы перебрать их все.
Например код:
/models.py
class Tourney(models.Model):
tourney = models.CharField()
tourney_1 = models.CharField()
tourney_2 = models.CharField()
class Stage(models.Model):
tourney = models.ForeignKey(Tourney, on_delete=models.CASCADE)
stage = models.CharField()
stage_1 = models.CharField()
stage_2 = models.CharField()
class Group(models.Model):
stage = models.ForeignKey(Stage, on_delete=models.CASCADE)
group = models.CharField()
group_1 = models.CharField()
group_2 = models.CharField()
Group
имеет отношение к Stage
, которое имеет отношение к Tourney
.
Итак, теперь мы хотим настроить для них API. Представьте, что у нас есть для них простые сериализаторы, которые включают все их поля и называются TourneySerializer
, StageSerializer
и GroupSerializer
.
Теперь попробуем отфильтровать модель Group
.
/views.py
class GroupViewSet(viewsets.ModelViewSet):
queryset = Group.objects.all()
serializer_class = serializers.GroupSerializer
def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
if 'tourney' in request.GET:
queryset = queryset.filter(stage__tourney__tourney=request.GET['tourney'])
if 'tourney_1' in request.GET:
queryset = queryset.filter(stage__tourney__tourney_1=request.GET['tourney_1'])
if 'tourney_2' in request.GET:
queryset = queryset.filter(stage__tourney__tourney_2=request.GET['tourney_2'])
if 'stage' in request.GET:
queryset = queryset.filter(stage__stage=request.GET['stage'])
if 'stage_1' in request.GET:
queryset = queryset.filter(stage__stage_1=request.GET['stage_1'])
if 'stage_2' in request.GET:
queryset = queryset.filter(stage__stage_2=request.GET['stage_2'])
if 'group' in request.GET:
queryset = queryset.filter(group=request.GET['group'])
if 'group_1' in request.GET:
queryset = queryset.filter(group_1=request.GET['group_1'])
if 'group_2' in request.GET:
queryset = queryset.filter(group_2=request.GET['group_2'])
serializer = self.get_serializer_class()(
queryset,
many=True)
return Response(serializer.data)
Здесь у нас есть один ViewSet с кучей очевидного кода, и их будет больше, если в таблицах будет больше таблиц и больше полей. У меня есть до 20 таблиц, и последняя таблица в этой связанной цепочке может фильтровать около 40 полей. Таким образом, можно иметь около 400 правил фильтрации для всех моделей, так что это примерно 800 строк глупого кода только для одной последней модели. Совсем не хорошо.
Так есть ли какой-нибудь известный способ сделать это? Эти проблемы кажутся обычными, так что, может быть, есть встроенные решения от Django или каких-либо его библиотек?