Django ManyToMany не сохраняется
У меня есть ModelMultipleChoiceField, которое я пытаюсь сохранить как ManyToMany отношения и пробовал почти каждое решение в Интернете, но по какой-то причине я не могу заставить мой сохранить. Я не получаю никаких ошибок, и остальная часть формы отправляется, только не ManyToMany.
Models.py
class Game(models.Model):
players = models.ManyToManyField(Student, blank=True)
other fields...
class Student(models.Model):
user_name = models.CharField(max_length=150, null=False, blank=False)
Forms.py
class Game(forms.ModelForm):
players = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(),
queryset=Student.objects.all(),
label="Players", required=False)
Views.py
def creategame(request):
if request.method == "POST":
form = Game(request.POST)
if form.is_valid():
form.save()
return redirect(reverse('management'))
else:
...
Я пробовал несколько подобных решений, но ни одно из них не сработало.
Views.py
def creategame(request):
if request.method == "POST":
form = Game(request.POST)
if form.is_valid():
new_game = form.save(commit=False)
new_game.save()
form.save_m2m()
return redirect(reverse('management'))
else:
...
Возможно, поле не включено в Meta
формы, отсюда и проблема. Мы можем исправить это с помощью:
class GameForm(forms.ModelForm):
class Meta:
model = Game
fields = ['players']
widgets = {'players': forms.CheckboxSelectMultiple()}
labels = {'players': 'Players'}
Затем это должно работать с видом:
def creategame(request):
if request.method == 'POST':
form = GameForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('management')
else:
form = GameForm()
return render(request, 'some-template.html', {'form': form})
Идеей может быть работа с классом на основе CreateView
[Django-doc] однако:
from django.urls import reverse_lazy
from django.views.generic.edit import CreateView
class GameCreateView(CreateView):
form_class = GameForm
template_name = 'some-template.html'
success_url = reverse_lazy('management')
и зарегистрируйте это в urls.py
как:
path('/game/create', GameCreateView.as_view(), 'name-of-view'),
Примечание: Обычно
Form
илиModelForm
заканчивается суффиксом…Form
, чтобы избежать коллизии с названием модели, и чтобы было понятно, что мы что мы работаем с формой. Поэтому, возможно, лучше использоватьGameForm
вместо.Game
Note: While most forms do not process media files, it is probably better to pass
request.FILES
[Django-doc] to the form anyway, such that if you later add an extra media field, all views that use the form will indeed handle the files properly.