Использование CreateView с 2 моделями одновременно

Я изучаю django. Я пытаюсь создать сайт, который регистрирует тренировки пользователя. Пользователь сможет создавать готовые тренировки.

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

Проблема, с которой я сталкиваюсь, заключается в том, что для создания тренировочной программы мне необходимо использовать модель WorkoutRoutine для создания объекта WorkoutRoutine. Затем мне также нужно использовать SetAmount, чтобы назначить упражнение, связанное с количеством сетов, объекту WorkoutRoutine.

Вот мой models.py:

from django.db import models
from django.contrib.auth import get_user_model
from django.core.validators import MaxValueValidator, MinValueValidator

class WorkoutRoutine(models.Model):
    title = models.CharField(max_length=25)
    owner = models.ForeignKey(
            get_user_model(),
            on_delete=models.CASCADE,
            )
    exercise = models.ManyToManyField(
            'Exercise',
            through='SetAmount',
            related_name='workoutRoutines'
            )

    def __str__(self):
        return self.title


class Exercise(models.Model):
    name = models.CharField(max_length=25)

    def __str__(self):
        return self.name


class SetAmount(models.Model):
    workout_routine = models.ForeignKey(
            'WorkoutRoutine', 
            related_name='set_amounts',
            on_delete=models.CASCADE, null=True
            )
    exercise = models.ForeignKey(
            'Exercise', 
            related_name='set_amounts', 
            on_delete=models.SET_NULL, 
            null=True, 
            blank=True
            )
    set_amount = models.IntegerField(
            default=0,
            validators=[
                MaxValueValidator(100),
                MinValueValidator(0),
                ]
            )

    def __str__(self):
        return str(self.set_amount)

Вот мой views.py:

from django.shortcuts import render
from django.views.generic import ListView, CreateView
from .models import WorkoutRoutine

class WorkoutRoutineListView(ListView):
    model = WorkoutRoutine 
    template_name = 'workout_routines.html'

class WorkoutCreateView(CreateView):
    model = WorkoutRoutine
    template_name = 'workout_creation.html'
    fields = ('title','exercise',)

Есть ли способ отредактировать WorkoutCreateView(CreateView), чтобы разрешить то, что я пытаюсь сделать? Или я должен создать функцию для достижения того, что я пытаюсь сделать?

Вам следует переопределить form_valid() метод CreateView. Он вызывается, если ваша форма действительна. Затем вы можете создать там свой экземпляр SetAmount.

def form_valid(self, form):
    # Easy way to obtain the through model (aka SetAmount)
    SetAmount = WorkoutRoutine.exercise.through
    # Assuming the exercise is selected in the form
    exercise = form.cleaned_data['exercise']
    # Create a SetAmount instance with the correct workout_routine and exercise from the form
    SetAmount.objects.create(
        workout_routine=form.instance,
        exercise=exercise,
        set_amount=100 # Swole
    )
    return super().form_valid(form)
Вернуться на верх