Как фильтровать набор запросов с помощью пользовательской функции

У меня есть следующие модели, и я пытаюсь применить некоторую фильтрацию.

В принципе, у меня есть модель игрока, у которого может быть несколько опытов, и я хочу отправить в запросе параметры xp, которые получат значение в годах, а мой набор запросов должен получить только игроков с как минимум таким количеством лет опыта в целом.

Метод calc_player_experience читает бросок опыта игроков и вычисляет количество опыта, которое имеет игрок, и возвращает true или false, если оно соответствует xp, полученному по параметрам запроса.

Как применить функцию к model.filter()? есть ли такая возможность?

models.py

class Player(BaseModel):
    name = models.CharField(_("name"), max_length=255, blank=True)

class Experience(BaseModel):
    player = models.ForeignKey(
        "players.Player", on_delete=models.CASCADE
    )
    team = models.CharField(_("team"), max_length=255)
    start_date = models.DateField(_("start_date"), null=True, blank=True)
    end_date = models.DateField(_("end_date"), null=True, blank=True)
views.py

class PlayersViewSet(viewsets.ModelViewSet):
    serializer_class = PlayerSerializer
    queryset = Player.objects.all()
    

    def get_queryset(self):
        """Filters the players to retrieve only those not archived and approved"""
        queryset = Player.objects.filter(is_approved=True, is_active=True)
        return apply_filters(self, queryset)

def apply_filters(obj, queryset):
    """Apply filters to given queryset"""

    xp = dict(obj.request.GET).get("xp", [])
    if xp:
        queryset = queryset.filter(lambda player: obj.calc_player_experience(player,xp[0])) 
        

В вашем файле views.py вам нужно вернуть кверисет из функции apply_filters. Убедитесь, что у вас есть возвращаемый queryset, даже если он пуст.


def apply_filters(obj, queryset):
    """Apply filters to given queryset"""

    xp = dict(obj.request.GET).get("xp", [])
    if xp:
        queryset = queryset.filter(lambda player: obj.calc_player_experience(player,xp[0])) 
    return queryset 
        
Вернуться на верх