I have the following models and I am trying to apply some filtering.
Basically I have this player model that can have multiple Experiences, and I want to send on my query params xp
that will receive a value in years, and my queryset should only retrieve the players with at least that amount of years of experience in total.
The calc_player_experience
method reads throw the players experience and calculates de amount of experience the player has and returns true
or false
if it meets the xp
received on the query params.
How do I apply a function to model.filter()
? is that a thing?
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]))
In your views.py you need to return the queryset from the apply_filters function. Make sure you have a queryset returned even if it is empty.
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.