Как добавить объект в отношения "многие-ко-многим" через форму на Django?

У меня есть следующие модели:

class Exercise(models.Model):
    exercise = models.CharField(max_length=166)
    series = models.CharField(max_length=2)
    reps = models.CharField(max_length=2)
    station = models.ForeignKey(Station)


class Workout(models.Model):
    member = models.ForeignKey(Member, on_delete=models.CASCADE)
    day = models.CharField(max_length=1)
    exercises = models.ManyToManyField(Exercise)

Я хочу иметь возможность иметь страницу, на которой отображается каждый Workout и пользователь может добавить Exercises при нажатии на кнопку +.

Так, это будет принимать Workout ID из URL, и при создании Exercise будет автоматически связывать его с этой тренировкой.

Я пробовал что-то в этом роде, но не думаю, что это работает:

if request.method == 'POST':
        np_form = NewWorkout(request.POST)
        ne_form = NovoExercise(request.POST)
    
        if ne_form.is_valid() and np_form.is_valid():
            nesave = ne_form.save()
            npsave = np_form.save(commit = False)
            npsave.exercises = nesave
            npsave.save()

В этом случае сначала сохраните оба объекта, а затем добавьте nesave к .exercises из npsave. Вам следует не сохранять npsave, так как ManyToManyField сохраняется не эта модель, а "скрытая" через модель:

if request.method == 'POST':
    np_form = NewWorkout(request.POST)
    ne_form = NovoExercise(request.POST)
    
    if ne_form.is_valid() and np_form.is_valid():
        nesave = ne_form.save()
        npsave = np_form.save()
        npsave.exercises.add(nesave)

Если вы, однако, не хотите создать новую тренировку, а просто добавить новое упражнение, вы можете сделать это с помощью представления, содержащего первичный ключ Workout:

from django.shortcuts import get_object_or_404

def my_view(request, pk):
    workout = get_object_or_404(Workout, pk=pk)
    if request.method == 'POST':
        ne_form = NovoExercise(request.POST)
        
        if ne_form.is_valid():
            nesave = ne_form.save()
            workout.exercises.add(nesave)
Вернуться на верх