Доступ к значениям поля manyToMany перед сохранением
Это моя Classroom
модель:
class Classroom(models.Model):
name = models.CharField(max_length=120)
faculty = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='faculty')
students = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='students')
def save(self, *args, **kwargs):
for faculty in self.faculty.all():
if not faculty.user_type == 'faculty':
raise ValidationError('Only users with user type as \'faculty\' can be assigned as faculty to a classroom')
for student in self.students.all():
if not student.user_type == 'student':
raise ValidationError('Only users with user type as \'student\' can be assigned as students to a classroom')
return super(Classroom, self).save(*args, **kwargs)
def __str__(self):
return self.name
В модели пользователя есть свойство user_type
, которое является либо faculty
, либо student
. В модели Classroom
я хочу убедиться, что только пользователи с типом user_type как faculty могут быть выбраны в качестве преподавателей и аналогично для студентов.
При попытке добавить данные с помощью django admin я получаю следующую ошибку:
ValueError at /admin/classroom/classroom/add/
"<Classroom: Some Class>" needs to have a value for field "id" before this many-to-many relationship can be used.
Не уверен, как это исправить, пожалуйста, подскажите. Заранее спасибо.
После нескольких часов исследований я нашел решение, которое работает. Я создал новую Django-форму для создания класса и переопределил метод clean
, и он работает.
class ClassroomForm(forms.ModelForm):
class Meta:
model = Classroom
fields = ['name', 'faculty', 'students']
required = ['name', 'faculty', 'students']
def clean(self) -> dict[str, Any]:
if 'faculty' in self.cleaned_data.keys():
for faculty in self.cleaned_data['faculty']:
if not faculty.user_type == 'faculty':
raise forms.ValidationError(f"Only users with user type as 'faculty' can be assigned as faculty to a classroom. {faculty.email} is not a faculty.")
if 'students' in self.cleaned_data.keys():
for student in self.cleaned_data['students']:
if not student.user_type == 'student':
raise forms.ValidationError(f"Only users with user type as 'student' can be assigned as students to a classroom. {student.email} is not a student.")
return super().clean()
Оставляю это здесь, чтобы это могло помочь кому-то еще.