繁体   English   中英

Django CreateView:如何在保存时执行操作

[英]Django CreateView: How to perform action upon save

我正在使用自定义 CreateView (CourseCreate) 和 UpdateView (CourseUpdate) 来保存和更新课程。 我想在保存课程时采取行动。 我将在新课程的讲师和用户之间创建一个新的多对多关系(如果它不存在的话)。

所以,我想将 Course 保存为 course,然后使用 course.faculty 创建新的关系。 实现这一目标的最佳地点在哪里?

我试图在视图中的 form_valid 中执行此操作,但在尝试访问 form.instance.faculty 时出现错误,因为尚未创建课程(在 CourseCreate 中)。 错误信息如下:

"Course: ..." 需要为字段 "course" 设置一个值,然后才能使用这种多对多关系。

它在 CourseUpdate 中也不起作用。 未创建 Assists 关系。 我应该在表格中尝试这个吗? 但我不确定如何将用户信息获取到表单。 谢谢你。

模型.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)

视图.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)

CreateViewUpdateViewform_valid()方法保存表单,然后重定向到成功 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

我建议使用 Django 的 Signal。 这是当模型发生某些事情时触发的操作,例如saveupdate 这样您的代码就可以保持干净(表单处理中没有业务逻辑),并且您确信它只会在save之后被触发。

#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  

可以像在 django 文档中一样返回 super()https ://docs.djangoproject.com/en/4.0/topics/class-based-views/generic-editing/

def form_valid(self, form):
    # This method is called when valid form data has been POSTed.
    # It should return an HttpResponse.
    form.send_email()
    return super().form_valid(form)

如果在调用保存函数时还需要修改 Course 对象,请使用 False 并在更改后保存对象

def form_valid(self, form):
    self.object = form.save(False)
    # make change at the object
    self.object.save()

    return HttpResponseRedirect(self.get_success_url())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM