Django表单预览-如何使用“清理的数据”

2024-04-18 19:37:41 发布

您现在位置:Python中文网/ 问答频道 /正文

感谢Insin回答了之前与此相关的question

他的回答很有效,但我对提供“干净的数据”感到困惑,或者更准确地说,如何使用它?

class RegistrationFormPreview(FormPreview):
    preview_template    = 'workshops/workshop_register_preview.html'
    form_template       = 'workshops/workshop_register_form.html'

    def done(self, request, cleaned_data):
        # Do something with the cleaned_data, then redirect
        # to a "success" page. 

        registration            = Registration(cleaned_data)
        registration.user       = request.user
        registration.save()
        # an attempt to work with cleaned_data throws the error: TypeError 
        # int() argument must be a string or a number, not 'dict'
        # obviously the fk are python objects(?) and not fk_id
        # but how to proceed here in an easy way?



        # the following works fine, however, it seems to be double handling the POST data
        # which had already been processed in the django.formtools.preview.post_post
        # method, and passed through to this 'done' method, which is designed to 
        # be overidden.
        '''
        form                    = self.form(request.POST)   # instansiate the form with POST data
        registration            = form.save(commit=False)   # save before adding the user
        registration.user       = request.user              # add the user
        registration.save()                                 # and save.
        '''

        return HttpResponseRedirect('/register/success')

为了快速参考,以下是post_post方法的内容:

def post_post(self, request):
    "Validates the POST data. If valid, calls done(). Else, redisplays form."
    f = self.form(request.POST, auto_id=AUTO_ID)
    if f.is_valid():
        if self.security_hash(request, f) != request.POST.get(self.unused_name('hash')):
            return self.failed_hash(request) # Security hash failed.
        return self.done(request, f.cleaned_data)
    else:
        return render_to_response(self.form_template,
            {'form': f, 'stage_field': self.unused_name('stage'), 'state': self.state},
            context_instance=RequestContext(request))

Tags: thetoselfformdatareturnrequestsave
1条回答
网友
1楼 · 发布于 2024-04-18 19:37:41

我以前从未尝试过您在这里使用ModelForm所做的操作,但您可能可以使用**运算符将已清理的数据字典扩展为注册构造函数所需的关键字参数:

   registration = Registration (**cleaned_data)

模型类的构造函数采用关键字参数,Django的模型元类将其转换为结果对象上的实例级属性。**运算符是一个调用约定,它告诉Python将字典扩展到那些关键字参数中。

换句话说。。。

你现在所做的无异于:

registration = Registration ({'key':'value', ...})

这不是您想要的,因为构造函数需要关键字参数,而不是包含关键字参数的字典。

你想做的就是

registration = Registration (key='value', ...)

类似于:

registration = Registration (**{'key':'value', ...})

再说一次,我从未尝试过,但似乎只要你对表单不做任何花哨的事情,比如向表单添加注册构造函数不期望的新属性,它就可以工作。在这种情况下,您可能需要在执行此操作之前修改已清理的数据字典中的项。

不过,通过使用表单预览实用程序,您似乎正在失去ModelForms中固有的一些功能。也许您应该将您的用例带到Django邮件列表中,看看这个API是否有一个潜在的增强,可以使它更好地与ModelForms一起工作。

编辑

除了我上面所描述的之外,您总是可以“手动”从清理过的数据字典中提取字段,并将它们传递到注册构造函数中,但是需要注意的是,在向模型中添加新字段时,您必须记住更新此代码。

registration = Registration (
    x=cleaned_data['x'],
    y=cleaned_data['y'],
    z=cleaned_data['z'],
    ...
)

相关问题 更多 >