现在来创建Schedule的新增页面,入口是某一个Project的Schedule列表页会有一个新增按钮。点击进入页面后会需要填写表单的每个字段。
image.png可以看到这里的字段仍需要填写project,这样是很不方便的。比较合理的是,在一个project的schedule列表页新建schedule的话,默认project字段为当前的project。且schedule的edit_by字段需默认为当前登录的用户。
先了解一下CreateView中的流程(其它View的流程也类似)。看源码可以知道:
image.pngCreateView是继承BaseCreateView,BaseCreateView继承ProcessFormView,另外还有SingleObjectTemplateResponseMixin和ModelFormMixin。这里其实是把视图函数的三个东西分开了,模板(SingleObjectTemplateResponseMixin),上下文/表单数据(ModelFormMixin),负责将这些联系起来的View(ProcessFormView)(个人理解)
CreateView的流程大致如下:
- 按照CreateView中定义的模板去创建视图,如果没有定义则按照SingleObjectTemplateResponseMixin中的模板去创建。
- 获取视图上的表单信息:get_form方法
- 判断表单中是否有无效信息(不符合规则的):is_valid方法
- 执行form_valid或者form_invalid方法
- 一直到form_valid后,会执行get_success_url方法,跳转到下个页面
这里,如果我们需要设置表单中某个字段的默认值,则自定义form_valid方法就可以啦。
# projtrack/views.py
class SchedNewView(generic.CreateView):
model = Schedule
template_name = 'projtrack/update_form.html'
fields = ['schedule_text', 'status', 'notes']
def form_valid(self, form):
# 从url中获取pk值,根据pk值找到对应的project
pk = self.kwargs.get(self.pk_url_kwarg)
form.instance.project = get_object_or_404(Project, pk=pk)
form.instance.edit_by = self.request.user.username
return super().form_valid(form)
现在fields可以不包含project字段了,在执行form_valid方法时,project字段和edit_by字段会根据我们自定义自动填充,再执行super的form_valid方法。
不过,添加成功后的跳转页面我们还没有设置,现在是404。
可以通过两种方式设置。
- 在SchedNewView中设置success_url的值,或者重写get_success_url方法
- 在projtrack/model.py中模型Schedule中添加方法get_absolute_url方法(推荐)
如果多个视图的成功页需要设置为同一个,则采用第2种方法更方便。比如,我们按第2种方法设置后,Schedule相关的UpdateView和CreateView修改或添加成功后都会执行该方法,不用再在view中去分别设置。
class Project(models.Model):
...
def get_absolute_url(self):
return reverse('projtrack:project')
class Schedule(models.Model):
...
def get_absolute_url(self):
return reverse('projtrack:schedule', kwargs={'pk': self.project_id})
这样添加后,新增或修改一个Project后会跳转到Project的列表页。新增或修改一个Schedule后会跳转到对应Project下的Schedule列表页。
网友评论