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



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

 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()

现在,我得到该表单无效,因为公司/上传/存储桶为空:

错误 表单:

  • 公司 此字段
  • 为必填字段。
  • 存储桶
  • 此字段为必填字段。
  • uploaded_by
  • 此字段为必填字段。
  • 但我确实设置了它们!我是否需要将它们设为空白=真,然后执行保存(提交=假(,更改它们,然后重新保存?如果是,为什么会这样?我确实更改了表格....

    试试这个:

    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()
    

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

    作业迟到了。在 ModelForm__init__()中,或在代码中:form = UploadForm(request.POST, request.FILES)行中,已创建一个实例并填充到窗体的initial。以后对实例的修改不会影响 form.initial 的值。

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

    因此,是的,您可以使它们blank=True或将它们从表单中排除,然后按照建议的方式进行操作。

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

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

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

    将一些字段值添加到 Django 中表单创建的模型实例的推荐方法是(正如我一直认为的那样(创建自定义模型表单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 文档中描述过

    最新更新