Использование 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)