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

Popular posts from this blog

basic authentication with http post params android -

vb.net - Virtual Keyboard commands -

How to get multiresult with multicondition in Sql Server -