Django中form.save()返回布尔值时,如何获取已保存的ModelForm对象?
解决django-postman WriteForm save()返回布尔值无法获取模型实例的问题
遇到这个问题很正常,django-postman的WriteForm的save()方法确实设计为返回布尔值表示保存是否成功,而不是模型实例。不过我们有几种简单的方式拿到保存后的Message对象:
方法1:直接从Form实例的instance属性获取
因为WriteForm是ModelForm的子类,只要表单验证通过且save(commit=True)执行成功,form.instance就是已经持久化到数据库的Message模型实例。你可以在视图里这样修改:
from postman.views import FormView class MyFormView(FormView): form_class = MyWriteForm def post(self, request, *args, **kwargs): form_class = self.get_form_class() form = self.get_form(form_class) files = request.FILES.getlist('file_field') if form.is_valid(): # 先执行父类的save逻辑,完成消息保存 save_success = form.save() if save_success: # 这里直接从form.instance拿到保存后的Message对象 message_obj = form.instance # 遍历处理上传的文件,关联到message_obj for file in files: # 示例:假设你有一个Attachment模型,关联Message和文件 # Attachment.objects.create(message=message_obj, file=file) pass return self.form_valid(form) else: return self.form_invalid(form)
方法2:重写WriteForm的save()方法,让它返回模型实例
如果你希望更直观地从save()获取实例,可以在自定义的MyWriteForm里重写save()方法,保留父类的逻辑同时返回实例:
from postman.forms import WriteForm from django import forms class MyWriteForm(WriteForm): file_field = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True})) def save(self, commit=True): # 先执行父类的保存逻辑,拿到成功状态 success = super().save(commit=commit) # 如果保存成功且提交到数据库,返回模型实例;否则返回原成功状态 if success and commit: return self.instance return success
然后在视图里就可以直接接收实例:
def post(self, request, *args, **kwargs): # ... 其他代码 if form.is_valid(): message_obj = form.save() if message_obj: # 因为save现在可能返回实例或布尔值,需要判断 for file in files: # 处理文件关联 pass return self.form_valid(form) # ...
注意事项
- 确保在调用
form.save()之后再处理文件,因为只有此时message_obj才被保存到数据库(有了主键ID),才能建立外键关联。 - 如果父类
WriteForm的save()方法有特殊逻辑(比如处理消息状态、收件人关联等),重写时一定要先调用super().save(),避免破坏原有功能。
内容的提问来源于stack exchange,提问作者43Tesseracts
相关产品推荐
相关产品推荐

