Home > Net >  Django Model Formset from ManyToMany not accepting queryset
Django Model Formset from ManyToMany not accepting queryset

Time:01-31

I have my model called Game that has a ManyToMany field.

consoles = models.ManyToManyField('Console', through='GameConsole')

That ManyToMany has some additional attributes

class GameConsole(models.Model):
    game            = models.ForeignKey(Game, on_delete=models.CASCADE)
    console         = models.ForeignKey(Console, on_delete=models.CASCADE)
    released        = models.DateTimeField    
    exclusive       = models.BooleanField(default=False)

I have a page where I want to create/edit those relations.

#forms.py
class GameConsoleForm(ModelForm):
    class Meta:
        model = GameConsole
        fields = ['console', 'released', 'exclusive']


#to prevent the submission of consoles with the same id (taken from django topics forms formsets)
class BaseGameConsoleFormSet(BaseFormSet):
    def clean(self):
        """Checks that no two alias have the same name."""
        if any(self.errors):
            # Don't bother validating the formset unless each form is valid on its own
            return
        console_ids = []
        for form in self.forms:
            if self.can_delete and self._should_delete_form(form):
                continue
            console= form.cleaned_data.get('console')
            if console in console_ids:
                raise ValidationError("Consoles in a set must be different.")
            console_ids.append(console)

NewGameConsoleFormSet = modelformset_factory(GameConsole, form=GameConsoleForm, formset=BaseGameConsoleFormSet, extra=1, can_delete=True)
GameConsoleFormSet = modelformset_factory(GameConsole, form=GameConsoleForm, formset=BaseGameConsoleFormSet, extra=0, can_delete=True)

The creation of multiple GameConsole's works fine. The problem is on the edition. On the views, when I do the following: formset = GameConsoleFormSet(queryset = game_consoles) I get the following error __init__() got an unexpected keyword argument 'queryset' which is strange, since I already used this logic with another model (normal table, not a ManyToMany) and it worked.

Full view:

def mng_game(request, game_id):

    #get game and verify if it exists
    game = Game.objects.filter(id = game_id).first()
    if not game:
        request.session['error_code'] = 33
        return redirect('error')

    game_consoles = game.consoles.all()
    form = GameForm(instance = game)

    if game_consoles :
        #TODO understand why this does not accept queryset
        formset = GameConsoleFormSet(queryset = game_consoles)
    else:
        formset = NewGameConsoleFormSet()

    consoles = Console.objects.all()
    context = {
        'form':form,
        'game': game,
        'formset': formset,
        'consoles': consoles
    }

    #change details from the Game
    if 'name' in request.POST:
        #update game

    return render(request, 'games/mng_game.html', context)

My question is: Am I doing something wrong, or a ManyToMany model formset does not support querysets for edition?

CodePudding user response:

You need to inherit BaseModelFormSet class instead of BaseFormSet so:

class BaseGameConsoleFormSet(BaseModelFormSet):
    ...
  • Related