【发布时间】:2012-03-31 00:52:30
【问题描述】:
如果我在编辑表单中,我想显示一条警告消息,如果我在 Django ModelForm 的创建表单中,我想隐藏它。
form.is_bound 告诉我之前是否填充了表单,但是如何测试 ModelForm 是否设置了现有实例?
我尝试了这个hasattr(form.instance, 'pk'),但这样做是否正确?
干杯,
纳蒂姆
【问题讨论】:
标签: django django-models django-forms
如果我在编辑表单中,我想显示一条警告消息,如果我在 Django ModelForm 的创建表单中,我想隐藏它。
form.is_bound 告诉我之前是否填充了表单,但是如何测试 ModelForm 是否设置了现有实例?
我尝试了这个hasattr(form.instance, 'pk'),但这样做是否正确?
干杯,
纳蒂姆
【问题讨论】:
标签: django django-models django-forms
尝试检查form.instance.pk 是否为None。
hasattr(form.instance, 'pk') 将始终返回 True,因为每个模型实例都有一个 pk 字段,即使它尚未保存到数据库中。
正如@Paullo 在 cmets 中指出的那样,如果您手动定义主键并指定默认值,则这将不起作用,例如default=uuid.uuid4.
【讨论】:
由于存在的实例将作为参数传递给关键字instance 以创建模型表单,因此您可以在自定义初始化程序中观察到这一点。
class Foo(ModelForm):
_newly_created: bool
def __init__(self, *args, **kwargs):
self._newly_created = kwargs.get('instance') is None
super().__init__(*args, **kwargs)
【讨论】:
我遇到了这个问题,但在我的情况下,我使用 UUID 进行 PK。尽管在大多数情况下接受的答案是正确的,但如果您不使用 Django 默认自动增量 PK,则会失败。
定义模型属性使我能够从模型、视图和模板中访问此值作为模型的属性
@property
def from_database(self):
return not self._state.adding
【讨论】:
我发现 self.instance 设置在 super().init 反正
class BaseModelForm(BaseForm):
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
initial=None, error_class=ErrorList, label_suffix=None,
empty_permitted=False, instance=None, use_required_attribute=None,
renderer=None):
...
if instance is None:
# if we didn't get an instance, instantiate a new one
self.instance = opts.model()
所以我们可以在 super().init 调用之前跟踪实例。 所以我的解决方案是覆盖 init 方法并设置自定义字段以跟踪所有后续表单的方法。
def __init__(self, *args: Any, instance=None, **kwargs: Any) -> None:
super().__init__(*args, instance=instance, **kwargs)
self.is_new_instance = not bool(instance)
及用法:
def _any_form_method(self):
if self.is_new_instance:
【讨论】: