2013-07-31 2 views
1

나는이 같은 주제에 관해 많은 질문이 있지만 하나의 지점에서 혼란 스럽다는 것을 알고있다. 의도적으로 두 개의 ModelChoiceFields를 폼에 표시하지만 게임 모델에 직접 연결하지는 않습니다.장고는 ModelChoiceField의 쿼리 세트를 필터링합니다. 내가 뭘 잘못 했습니까?

내가 검색어 세트 필터를 설정할 때입니다 혼란 스러워요 Views.py

def game_add(request, match_id): 
    game = Game() 
    try: 
     match = Match.objects.get(id=match_id) 
    except Match.DoesNotExist: 
     # we have no object! do something 
     pass 

    game.match = match 

    # get form 
    form = AddGame(request.POST or None, instance=game) 
    form.fields['home_team'].queryset = Player.objects.filter(team=match.home_team) 

    # handle post-back (new or existing; on success nav to game list) 
    if request.method == 'POST': 
     if form.is_valid(): 
      form.save() 
      # redirect to list of games for the specified match 
      return HttpResponseRedirect(reverse('nine.views.list_games')) 

    ... 

class AddGame(forms.ModelForm): 
    won_lag = forms.ChoiceField(choices=[('1','Home') , ('2', 'Away') ]) 
    home_team = forms.ModelChoiceField(queryset=Player.objects.all()) 
    away_team = forms.ModelChoiceField(queryset=Player.objects.all()) 

    class Meta: 
     model = Game 
     fields = ('match', 'match_sequence') 

forms.py :

나는 다음 있습니다. 먼저 내가 시도 :

form.home_team.queryset = Player.objects.filter(team=match.home_team) 

하지만 난

AttributeError at /nine/games/new/1 
'AddGame' object has no attribute 'home_team' 
... 

그래서 난 다음에 변경이 오류가 발생했습니다 :

form.fields['home_team'].queryset = Player.objects.filter(team=match.home_team) 

지금 (다른 게시물을 읽은 후) 그것을 잘 작동합니다 .

제 질문은 두 줄의 차이점은 무엇입니까? 왜 두 번째 작품은 처음 작품이 아닌가? 나는 그것이 초보자 (나는 하나)라는 것이 확실하지만 나는 당황 스럽다.

도움을 주시면 감사하겠습니다.

form = AddGame(request.POST or None, instance=game) 

그래서 form 클래스 AddGame의 양식 개체입니다 (사이드 참고 : 당신이 혼동을 피하기 위해 AddGameForm로 이름을 변경해야합니다)

답변

3

장고 양식이 metaclasses입니다입니다 그 정의에 주어진 정보. 즉, AddGame 양식을 정의 할 때 표시되는 내용을 정확히 알 수 없습니다.당신이 그것을 인스턴스화 할 때, metaclass는 제공된 필드에 적절한 인스턴스를 반환합니다

>>> type(AddGame()) 
<class 'your_app.forms.AddGame'> 

그래서, 인스턴스와 함께, 당신은 단순히 form.field를 수행하여 필드에 액세스 할 수 있습니다. 사실, 그보다 조금 더 복잡합니다. 액세스 할 수있는 필드에는 두 가지 유형이 있습니다. form['field']을 사용하면 BoundField에 액세스하게됩니다. 출력 및 raw_input에 사용됩니다.

form.fields['fields']을하면 field that python can understand에 액세스하게됩니다. 왜냐하면 from이 이미 입력을 받았기 때문에 유효성 검사와 데이터 변환이 일어나는 곳이 있기 때문입니다. 사실 이것들은 사용 된 필드입니다. the general process of validation은 좀 더 복잡합니다.

이 문제가 다소 해결 되었기를 바라지 만, 보시다시피, 전체 form's API은 정말 크고 복잡합니다. 최종 사용자에게는 매우 간단하지만 커튼 뒤에는 많은 프로그래밍이 있습니다 :)

링크를 읽는 것은 의심의 여지를 없애고이 매우 유용한 주제와 장고에 대한 지식을 향상시킵니다.

행운을 빈다.

업데이트 : 덧붙여서, 파이썬의 메타 클래스에 대해 더 알고 싶다면 this is a hell of an answer 주제에 관해서.

0

views.py에서는이 라인을 가지고있다.

home_teamAddGame 클래스의 필드이므로 form 개체의 특성이 아닙니다. 그래서 form.home_team을 통해 액세스 할 수 없습니다.

그러나 Django Form API는 어떤 양식 객체에도 fields 속성을 제공하며, dict에는 모든 양식 필드가 들어 있습니다. 그래서 form.fields['home_team']에 액세스 할 수 있습니다.

>>> type(AddGame) 
<class 'django.forms.forms.DeclarativeFieldsMetaclass'> 

그들은 기본적에 따라 양식 인스턴스를 생성 : 액세스 할 수있는 이유

그리고 마지막으로 home_teamModelChoiceField이기 때문에, 그것은 queryset 속성을 포함 할 수있는, 즉 form.fields['home_team'].queryset

관련 문제