Django CreateView: как выполнить действие при сохранении
Я использую пользовательский CreateView (CourseCreate) и UpdateView (CourseUpdate) для сохранения и обновления курса. Я хочу принять меры, когда курс сохранен. Я создам новые отношения "многие ко многим" между инструктором нового курса и пользователем (если он еще не существует).
Итак, я хочу сохранить курс как курс, а затем использовать course.faculty для создания новых отношений. Где лучшее место, чтобы это произошло?
Я пытаюсь сделать это в form_valid в представлениях, но я получаю ошибки при попытке получить доступ к form.instance.faculty bc, курс еще не создан (в CourseCreate). Сообщение об ошибке выглядит следующим образом:
"Курс:..." должен иметь значение для полевого курса, прежде чем можно использовать отношения "многие ко многим".
Он также не работает в CourseUpdate. Отношение Assists не создано. Должен ли я попробовать это в форме? Но я не уверен, как получить информацию о пользователе в форме.
Спасибо.
models.py
class Faculty(models.Model):
last_name = models.CharField(max_length=20)
class Course(models.Model):
class_title = models.CharField(max_length=120)
faculty = models.ManyToManyField(Faculty)
class UserProfile(models.Model):
user = models.OneToOneField(User)
faculty = models.ManyToManyField(Faculty, through='Assists')
class Assists(models.Model):
user = models.ForeignKey(UserProfile)
faculty = models.ForeignKey(Faculty)
views.py
class CourseCreate(CreateView):
model = Course
template_name = 'mcadb/course_form.html'
form_class = CourseForm
def form_valid(self, form):
my_course = form.instance
for f in my_course.faculty.all():
a, created = Assists.objects.get_or_create(user=self.request.user.userprofile, faculty=f)
return super(CourseCreate, self).form_valid(form)
class CourseUpdate(UpdateView):
model = Course
form_class = CourseForm
def form_valid(self, form):
my_course = form.instance
for f in my_course.faculty.all():
a, created = Assists.objects.get_or_create(user=self.request.user.userprofile, faculty=f)
return super(CourseUpdate, self).form_valid(form)
Ответы
Ответ 1
Метод form_valid()
для CreateView
и UpdateView
сохраняет форму, затем перенаправляет URL-адрес успеха. Невозможно выполнить return super()
, потому что вы хотите делать материал между сохраненным объектом и перенаправлением.
Первый вариант - не вызывать super()
и дублировать две строки в вашем представлении. Преимущество этого в том, что он очень четко показывает, что происходит.
def form_valid(self, form):
self.object = form.save()
# do something with self.object
# remember the import: from django.http import HttpResponseRedirect
return HttpResponseRedirect(self.get_success_url())
Второй вариант - продолжить вызов super()
, но не возвращать ответ до тех пор, пока вы не обновите связь. Преимущество этого заключается в том, что вы не дублируете код в super()
, но недостатком является то, что не так ясно, что происходит, если вы не знакомы с тем, что делает super()
.
def form_valid(self, form):
response = super(CourseCreate, self).form_valid(form)
# do something with self.object
return response
Ответ 2
Я бы предложил использовать Django Signal. Это действие, которое запускается, когда что-то происходит с моделью, например, сохранение или обновление. Таким образом, ваш код остается чистым (без бизнес-логики в обработке форм), и вы уверены, что он запускается только после сохранения.
#views.py
from django.dispatch import receiver
...
@receiver(post_save, sender=Course)
def post_save_course_dosomething(sender,instance, **kwargs):
the_faculty = instance.faculty
#...etc