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