2009-07-31 4 views
4

Моей проблемы похоже на Django Passing Custom Form Parameters to FormsetДжанго Передачи пользовательской формы Параметров для ModelFormset

Ive есть эти классы

class Game(models.Model): 
    home_team = models.ForeignKey(Team, related_name='home_team') 
    away_team = models.ForeignKey(Team, related_name='away_team') 
    round = models.ForeignKey(Round) 

TEAM_CHOICES = ((1, '1'), (2, 'X'), (3, '2'),) 

class Odds(models.Model): 
    game = models.ForeignKey(Game, unique=False) 
    team = models.IntegerField(choices = TEAM_CHOICES) 
    odds = models.FloatField() 
    class Meta: 
     verbose_name_plural = "Odds" 
     unique_together = (
      ("game", "team"), 
     ) 

class Vote(models.Model): 
    user = models.ForeignKey(User, unique=False) 
    game = models.ForeignKey(Game) 
    score = models.ForeignKey(Odds) 
    class Meta: 
     unique_together = (
      ("game", "user"),) 

И я определил свой собственный modelformset_factory:

def mymodelformset_factory(ins): 
    class VoteForm(forms.ModelForm): 
     score = forms.ModelChoiceField(queryset=Odds.objects.filter(game=ins), widget=forms.RadioSelect(), empty_label=None) 
     def __init__(self, *args, **kwargs): 
      super(VoteForm, self).__init__(*args, **kwargs) 
     class Meta: 
      model = Vote 
      exclude = ['user'] 
    return VoteForm 

И я использую это примерно так:

 VoteFormSet = modelformset_factory(Vote, form=mymodelformset_factory(v), extra=0) 
     formset = VoteFormSet(request.POST, queryset=Vote.objects.filter(game__round=round, user=user)) 

Это показывает вид:

выпадающих из игры (ы) в раунде, указанной и должно отображать 3 радиокнопку для Odds, но я не знаю, что передать в качестве параметра к mymodelformset_factory. Если v = Game.objects.get (pk = 1), то он отображает только игру с pk = 1 для ВСЕХ игр, мне нужна игра v = Game.objects.get (pk = ", которая связана с шансами относительно »), если вы поймаете мой дрифт.

ответ

4

Я думаю, вы хотите внести некоторые изменения в свою пользовательскую фабричную функцию. Он должен возвращать класс formet, а не форму. Как об этом:

def make_vote_formset(game_obj, extra=0): 
    class _VoteForm(forms.ModelForm): 
     score = forms.ModelChoiceField(
      queryset=Odds.objects.filter(game=game_obj), 
      widget=forms.RadioSelect(), 
      empty_label=None) 

     class Meta: 
      model = Vote 
      exclude = ['user',] 
    return modelformset_factory(Vote, form=_VoteForm, extra=extra) 

Тогда в вашем представлении кода:

current_game = Game.objects.filter(id=current_game_id) 
VoteFormSet = make_vote_formset(current_game) 
formset = VoteFormSet(
      request.POST, 
      queryset=Vote.objects.filter(game__round=round, user=user)) 
+0

Это, кажется, работает для меня подобной проблемы! – balleyne

0

Другим решением является подкласс BaseModelFormSet и переопределить _construct_forms метод. По умолчанию BaseFormSet метод _construct_form звонит в _construct_forms только один аргумент с того, что:

# django/forms/formsets.py 
def _construct_forms(self): 
    # instantiate all the forms and put them in self.forms 
    self.forms = [] 
    for i in xrange(self.total_form_count()): 
     self.forms.append(self._construct_form(i)) 

но может быть любое количество ключевых слов аргументах:

# django/forms/formsets.py 
def _construct_form(self, i, **kwargs): 

Итак, вот мой метод вид и форма, получает дополнительный параметр в инициализации из _construct_form:

# view 

def edit(request, id): 
    class ActionsFormSet(BaseModelFormSet): 
     department = request.user.userdata.department.pk 

     def _construct_forms(self): 
      self.forms = [] 
      for i in range(self.total_form_count()): 
       self.forms.append(self._construct_form(i, dep=self.department)) 

    actions_formset = modelformset_factory(Action, form=ActionForm, extra=0, can_delete=True, formset=ActionsFormSet) 
    ... 


# form 

class ActionForm(forms.ModelForm): 
    def __init__(self, dep=0, *args, **kwargs): 
     super(ActionForm, self).__init__(*args, **kwargs) 
     self.fields['user'].choices = [(u.pk, u.first_name) for u in User.objects.filter(userdata__department=dep)] 

    class Meta: 
     model = Action 
     exclude = ('req',) 
Смежные вопросы