Подтвердить что ты не робот

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)
4b9b3361

Ответ 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