django - queryset diference - not working as i expect -
another newbie problem afraid. have form 3 lists. goal being change queryset 2 of lists (see code in view)
form.py
class addgameform(forms.modelform): won_lag = forms.choicefield(choices=[('1','home') , ('2', 'away') ], ) home_team = forms.modelchoicefield(queryset=player.objects.all(),required=true ) away_team = forms.modelchoicefield(queryset=player.objects.all(), required=true ) class meta: model = game fields = () view.py
def game_add(request, match_id): # used create new game """ return http response page creating new game """ # adding new game make new 1 game = game() # match specified in querystring because need figure out home team # , away team are. try: match = match.objects.get(id=match_id) except match.doesnotexist: # have no object! #todo: redirect list match page? pass # form form = addgameform(request.post or none, instance=game) # change queryset home , away team show players on team # , have not played in game need "difference" between # team members , players have played in match home_players = player.objects.filter(team=match.home_team) # home team members away_players = player.objects.filter(team=match.away_team) # away team members already_played_in_match_players = game.objects.filter(match=match) # both home , away players # have played in game on match form.fields['home_team'].queryset = home_players.exclude(pk__in=already_played_in_match_players) form.fields['away_team'].queryset = away_players.exclude(pk__in=already_played_in_match_players) ... in db have following:
team 1 player 1 player 2 team 2 player 3 match 1 no games so when open form, expected, home_team list shows both player1, player2 , away_team list shows player3
so choose player 1 , player3, , save game. db has following data
team 1 player 1 player 2 team 2 player 3 match 1 game 1 between player1 , player3 i decide add game open gameaddform , expect have home_team list show player2 , away_team list show no players.
however, in reality, happens home_team list acts expected, but away_team list still shows player 3.
i totally confused why works correctly home team not away team.
any suggestions?
thanks in advance guidance can provide.
ok, figured out. problem following line:
already_played_in_match_players = game.objects.filter(match=match) which returns queryset of games, not players.
since wanted players, had start player.object. meant had query through game → player1 , game → player2 relations backwards. here's docs it:
lookups span relationships span relationship, use field name of related fields across models, separated double underscores, until field want ... refer “reverse” relationship, use lowercase name of model. i broke several steps clarity.
inner_query = game.objects.filter(match=match) # gets games in match then used following:
player.objects.filter(player1__in=inner_query) which says, player objects referenced player1 foreignkey in game object in innerquery queryset.
next used | (pipe) union queryset player1 , player2 resulted in line:
already_played_players = player.objects.filter(player1__in=inner_query) | player.objects.filter(player2__in=inner_query) this had desired affect of giving me list of players had played in match.
summary of change
i changed offending line following:
... inner_query = game.objects.filter(match=match) # games in match # use reverse relation player1 union player2 players have played in match far already_played_players = player.objects.filter(player1__in=inner_query) | player.objects.filter(player2__in=inner_query) ...
Comments
Post a Comment