Pregunta

Mi problema es similar a Django pasando parámetros de formulario personalizado al conjunto de formularios

Tengo estas clases

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"),)

Y he definido mi propio 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 

Y lo uso así:

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

Esto muestra el formulario:

cuadro desplegable de Juego (s) en la Ronda especificada y se supone que muestra 3 botones de radio para las Probabilidades, pero no sé qué pasar como parámetro a mymodelformset_factory .. If v = Game.objects. get (pk = 1) obviamente solo muestra Juego con pk = 1 para TODOS los juegos, lo que necesito es v = Game.objects.get (pk = " juego que está conectado a las probabilidades con respecto a ") si captas mi deriva ..

¿Fue útil?

Solución

Creo que desea realizar algunos cambios en su función de fábrica personalizada. Debería devolver la clase de conjunto de formularios, no el formulario. ¿Qué tal esto?

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)

Luego, en su código de vista:

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))

Otros consejos

Otra solución es subclasificar BaseModelFormSet y anular el método _construct_forms . Por defecto, el método BaseFormSet _construct_form invoca _construct_forms con un solo argumento, i:

# 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))

pero puede haber cualquier número de argumentos de palabras clave:

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

Entonces, aquí está mi método de vista y formulario que recibe parámetros adicionales en init de _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',)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top