Django UpdateView及其相关模型
我有以下情况,我不知道如何进行更新:Django UpdateView及其相关模型,django,django-class-based-views,Django,Django Class Based Views,我有以下情况,我不知道如何进行更新: #models.py class Task(models.Model): creation_date = models.DateField( default=None, ) name = models.CharField( max_length=255, ) description = models.TextField( max_length=500, b
#models.py
class Task(models.Model):
creation_date = models.DateField(
default=None,
)
name = models.CharField(
max_length=255,
)
description = models.TextField(
max_length=500,
blank=True,
null=True,
)
class TaskDetails(models.Model):
PEND = 1
COMP = 2
TASK_STATUS = (
(PEND, 'pending'),
(COMP, 'completed'),
)
task = models.OneToOneField(
Task,
primary_key=True,
on_delete=models.CASCADE
)
solution = models.CharField(
max_length=255,
)
due_date = models.DateField(
null=True,
default=None,
blank=True,
)
status = models.PositiveSmallIntegerField(
default=1,
choices=TASK_STATUS,
)
现在我的观点是
#views.py
class TaskUpdate(UpdateView):
model = Task
second_model = TaskDetails
form_class = TaskForm
second_form_class = TaskDetailsForm
pk_url_kwarg = 'task_id'
def get_context_data(self, **kwargs):
context = super(TaskUpdate, self).get_context_data(**kwargs)
if self.request.method == 'POST':
details_form = self.second_form_class(self.request.POST, prefix='details')
else:
details_object = self.second_model.objects.get(pk=self.kwargs.get(self.pk_url_kwarg))
details_form = self.second_form_class(instance=details_object, prefix='details')
context['details_form'] = details_form
return context
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.form_class(request.POST)
details_form = self.second_form_class(request.POST, prefix='details')
if form.is_valid() and details_form.is_valid():
return self.form_valid(form, details_form)
else:
return self.form_invalid(form, details_form)
def form_valid(self, form, details_form):
form.instance.creation_date = datetime.now().date()
self.object = form.save()
details_form.instance.task = self.object
details_form.save()
return HttpResponseRedirect(self.success_url)
def form_invalid(self, form, details_form):
return self.render_to_response(self.get_context_data(form=form, details_form=details_form))
我还有模型表单:TaskForm和TaskDetailsForm。与此无关。
这两个表格将同时显示和提交。
但它不更新Task和TaskDetails表中的现有记录,而是在这两个表中创建一个新记录
我认为我的问题在形式上有效。我应该在那里放什么?
非常感谢在方法后创建表单时没有实例。您必须在那里传递实例
def post(self, request, *args, **kwargs):
# get current task
obj = self.get_object()
#initiate the task form with this object as instance
form = self.form_class(request.POST, instance=obj)
#get realted details object or None.
#I can't check if this string works, but it should.
details_obj = getattr(object, 'taskdetails', None)
#initiate the details_form with this details_object as instance
details_form = self.second_form_class(request.POST, prefix='details',
instance=details_obj)
if form.is_valid() and details_form.is_valid():
return self.form_valid(form, details_form)
else:
return self.form_invalid(form, details_form)
def form_valid(self, form, details_form):
#save object
obj = form.save(commit=False)
obj.creation_date = datetime.now().date()
obj.save()
#save details_object
details_obj = details_form.save(commit=False)
details_obj.task = obj
details_obj.save()
return HttpResponseRedirect(self.success_url)
我认为这应该行得通。在这种情况下,您不需要
form\u valid
和form\u invalid
方法
def post(self, request, *args, **kwargs):
response = super(TaskUpdate, self).post(request, *args, **kwargs)
details_form = self.second_form_class(self.request.POST, prefix='details')
if details_form.is_valid():
task = self.get_object()
self.second_model.objects.filter(task=task)
.update(**details_form.cleaned_data)
return response
return render(request, self.template_name, {
'form': self.get_form(self.get_form_class()),
'details_form': details_form,
})
PS:putrelated\u name=task\u details
用于OneToOneField
和auto\u now\u add=True
用于任务的创建日期
尽管如此,为什么不将任务详细信息包含到任务中并停止使用此OneToOneKey?您可以在代码中演示如何执行此操作吗?事实上,我在Django工作是新手!谢谢你,亲爱的。是的,这也行。但是你没有尽可能地使用
UpdateView
。这个也可以!但由于我正在学习并希望正确使用GCBV,我将选择的解决方案。没有问题(:我的项目中根本没有使用CBV,因此他的答案肯定更适合您的情况。此处如果详细信息\u表单有效()
?我做了一些编辑来修复一些错误,但仍然出现了这个错误:“TaskDetails”对象没有属性“update”是的,因为您从filter
更改为get
。另一种方法是使用task.task\u details
对象,并逐个更新其字段,但我是使用filter
得到这个错误的:un哈希类型:“dict”如何解决它?现在可以了。小错误,它应该是详细信息\u表单。清理的\u数据
而不是{details\u表单。清理的\u数据}
,因为这已经是一个字典了