我想在保存之前更改表单的实例。我需要在视图中设置如下的某些信息:
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为空:
错误表格:
但我确实设定了它们!我是否需要将它们设为空白= True,然后执行保存(commit = false),更改它们,然后重新保存?如果是,为什么会这样?我确实改变了形式......
答案 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=True
或exclude them from the form然后关注 the suggested way。
答案 2 :(得分:0)
其实你在这里做了几件奇怪的事情。
第一:
为什么要分配到company_id
,uploaded_by_id
和bucket_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
中描述的解决方案