Чего я хочу достичь:
Мне нужен список пользователей с их соответствующими миссиями и фильтрация по дате начала миссий.
# Pseudo json
User 1
- mission 1
- mission 2
User 2
- mission 1
- mission 2
- mission 3
Моя структура данных:
Модели:
class Mission(models.Model):
start = models.DateTimeField()
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="missions")
Сериализаторы:
# Mission
class MissionSerializer(serializers.ModelSerializer):
class Meta:
model = Mission
fields = (
'start',
'end',
)
# User
class UserSerializer(serializers.ModelSerializer):
missions = MissionSerializer(many=True)
class Meta:
model = MyUser
fields = (
'username',
'missions',
)
Наборы представлений:
# Filter
class UserFilter(django_filters.FilterSet):
class Meta:
model = MyUser
fields = {
'missions__start': ['gte','lt']
}
# Viewset
class UserViewset(viewsets.ModelViewSet):
filter_backends = (filters.OrderingFilter, filters.DjangoFilterBackend,)
filter_class = UserFilter
serializer_class = UserSerializer
@list_route(methods=['get'])
def listCalendar(self, request):
prefetched_missions = Prefetch('missions', queryset=Mission.objects.all())
objects_list = MyUser.objects.prefetch_related( prefetched_missions )
objects_list = self.filter_queryset(objects_list)
serializer = UserSerializer(objects_list, many=True)
return Response(serializer.data)
Моя проблема:
При вызове этого URL:
/api/users/listCalendar/?start__gte=2015-06-29&start__lt=2015-08-10
Фильтр игнорируется, и я не могу понять, как заставить его работать. У меня есть интуиция, что проблема связана с Mission.objects.all()
в ViewSet, который, вероятно, должен быть чем-то вроде: Mission.objects.filter(*But what here?*)
Любая помощь будет очень высоко ценится!
Редактировать 1:
Есть прогресс! Но все еще не работает... Как вы предложили, Марк Галлоуэй, я попытался вызвать следующий URL-адрес:
/api/users/listCalendar/?missions__start__gte=2015-06-29&missions__start__lt=2015-08-10
Но это запрос, который выполняется:
SELECT "app_myuser"."id", "app_myuser"."username"
FROM "app_myuser"
INNER JOIN "app_mission" ON ( "app_myuser"."id" = "app_mission"."user_id" )
INNER JOIN "app_mission" T4 ON ( "app_myuser"."id" = T4."user_id" )
WHERE ("app_mission"."start" >= '2015-07-06T00:00:00+00:00'::timestamptz
AND T4."start" < '2015-07-12T00:00:00+00:00'::timestamptz)
ORDER BY "app_myuser"."username" ASC;
Как видите, INNER JOIN 2 вместо 1. По некоторым причинам он принимает 2 отфильтрованных поля, как если бы они были в отдельных таблицах. В результате мои результаты дублируются.