在保存之前更改表单实例Django

时间:2012-05-23 15:22:57

标签: django django-models django-forms

我想在保存之前更改表单的实例。我需要在视图中设置如下的某些信息:

 class UploadedFile(models.Model):

     file = models.FileField(storage=s3store, upload_to=custom_upload_to)
     slug = models.SlugField(max_length=50, blank=True)
     bucket = models.ForeignKey(S3Bucket, blank=False)
     uploaded_by = models.ForeignKey(User, related_name='uploaded_by', blank=False)
     company = models.ForeignKey(Company, blank=False)

-

class UploadForm(ModelForm):

    class Meta:
        model = UploadedFile    

-

form = UploadForm(request.POST, request.FILES)
form.instance.company_id = r_user.company.id
form.instance.uploaded_by_id = r_user.id
form.instance.bucket_id = r_user.company.s3_bucket_id
if form.is_valid():
     form_object = form.save()

现在,我知道表单无效,因为company / uploaded / bucket为空:

错误表格:

  • 公司
  • 此字段是必填字段。
  • bucket
  • 此字段是必填字段。
  • uploaded_by
  • 此字段是必填字段。
  • 但我确实设定了它们!我是否需要将它们设为空白= True,然后执行保存(commit = false),更改它们,然后重新保存?如果是,为什么会这样?我确实改变了形式......

    3 个答案:

    答案 0 :(得分:2)

    试试这个:

    data = request.POST.copy()
    data['company_id'] = r_user.company.id
    data['uploaded_by_id'] = r_user.id
    data['bucket_id'] = r_user.company.s3_bucket_id
    
    form = UploadForm(data, request.FILES)
    if form.is_valid():
         form_object = form.save()
    

    这样您就可以在创建表单之前设置数据。

    答案 1 :(得分:1)

    作业迟到了。在__init__() ModelForm或您的代码中:form = UploadForm(request.POST, request.FILES)行,an instance has been created and populated to initial of the form。稍后对实例进行修改不会影响form.initial的值。

    此外,如果您想在后端自动填写某些字段,请不要将其呈现给用户。

    因此,是的,你可以让他们blank=Trueexclude them from the form然后关注 the suggested way

    答案 2 :(得分:0)

    其实你在这里做了几件奇怪的事情。

    第一: 为什么要分配到company_iduploaded_by_idbucket_id?但是,您在模型中获得了这些字段 - 它是为此模型创建的表中列的名称 - 您应该在此处直接使用ORM功能,例如form.instance.company = r_user.company

    第二: 表单验证应用于form.fields而不是它的实例属性,并且一旦创建表单并将其限制为提供的值,就无法更改它们。

    将一些字段值添加到Django中由表单创建的模型实例的推荐方法(正如我一直认为的那样)是创建自定义ModelForm,并在Meta类中指定您希望允许用户编辑的所有字段。对于你的情况:

    class UploadForm(ModelForm):
    
        class Meta:
            model = UploadedFile
            fields = ('file', 'slug')
    

    然后拨打form_object = form.save()而不是致电form_object = form.save(commit=False)。现在,您已获得模型实例,其中包含已填写表单的所有字段,因此您可以添加所需内容:例如form_object.company = r_user.company。最后,不要忘记在模型实例本身上调用save()将其存储在数据库中。

    它在Django文档here

    中描述的解决方案