Python 如何使用Django表单';获取\u field()方法的\u initial\u?
我有两种型号Python 如何使用Django表单';获取\u field()方法的\u initial\u?,python,django,Python,Django,我有两种型号公司和包装,定义如下: class Company(models.Model): default_package = models.OneToOneField( Package, blank=True, null=True, related_name='default_for_%(class)s') class Package(models.Model): company = models.Forei
公司
和包装
,定义如下:
class Company(models.Model):
default_package = models.OneToOneField(
Package,
blank=True,
null=True,
related_name='default_for_%(class)s')
class Package(models.Model):
company = models.ForeignKey('lucy_web.Company')
其中lucy\u web
是应用程序的名称。因此,包
和公司
之间存在多对一关系,此外,公司
和其默认包
之间存在一对一关系
我正在为Package
对象制作一个ModelForm
,它的简化版本是
class PackageForm(forms.ModelForm):
class Meta:
model = Package
fields = [
'is_default',
]
is_default = forms.BooleanField(initial=True, required=False)
def save(self, *args, **kwargs):
package = super().save(*args, **kwargs)
if self.cleaned_data['is_default']:
package.company.default_package = package
package.company.save()
return package
因此,当为默认值时
设置为True
,包将被设置为其公司的默认包
问题在于,此表单在通用CreateView
和UpdateView
中都使用,并且在UpdateView
中,即使包不是默认包,是默认的
仍然设置为True
。这将使用户很容易在不经意间将包更改为默认值,而实际上他们只是想更改另一个字段
我想将的首字母
设置为默认值
,这样,对于未绑定表单,它是真的
,对于绑定表单,它是真的
,只有当包
有公司的默认值
时。我试图将其添加到\uuuu init\uuuu()
,如下所示:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.instance and self.instance.default_for_company:
self.initial['is_default'] = True
但是,不幸的是,对于非默认的包,这会导致RelatedObjectDoesNotExist
错误:
File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/dashboard/forms/packages.py" in __init__
60. if self.instance and self.instance.default_for_company:
File "/Users/kurtpeek/Documents/Dev/lucy/lucy-web/venv/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py" in __get__
407. self.related.get_accessor_name()
Exception Type: RelatedObjectDoesNotExist at /dashboard/packages/55
Exception Value: Package has no default_for_company.
另外,重写
\uuuu init\uuuu()
似乎有点“黑客”,而且该方法似乎就是为此而设计的。这是我可以为我的PackageForm
定义的东西,以这种方式“动态”获取字段的初始值吗?(从文档中我不清楚如何在这种情况下应用它)。您覆盖\uuuuu init\uuuu
方法的方法在我看来是可行的。使用hasattr
避免出现relatedObjectsDoesNotExist
异常
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.instance and hasattr(self.instance, 'default_for_company'):
self.initial['is_default'] = True
我以前没有为字段使用过
get\u initial\u
。看起来您可以执行以下操作:
def get_initial_for_field(self, field, field_name):
if field_name == 'is_default':
return bool(self.instance and hasattr(self.instance, 'default_for_company'))
return super().get_initial_for_field(field, field_name)
在我看来,您重写
\uuuu init\uuu
方法的方法是可行的。使用hasattr
避免出现relatedObjectsDoesNotExist
异常
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.instance and hasattr(self.instance, 'default_for_company'):
self.initial['is_default'] = True
我以前没有为字段使用过
get\u initial\u
。看起来您可以执行以下操作:
def get_initial_for_field(self, field, field_name):
if field_name == 'is_default':
return bool(self.instance and hasattr(self.instance, 'default_for_company'))
return super().get_initial_for_field(field, field_name)
后一种方法似乎有效,谢谢!我唯一剩下的问题是,对于
CreateView
(新软件包的表单),是默认的的初始值
没有设置为True
。我注意到在这种情况下,实际上,self.initial
是一个空字典,所以我可以对它进行特殊处理,但有没有更好的方法?get_initial_for_field
在我尝试它时,与CreateView
配合得很好,所以您只需要确保在方法中使用了正确的逻辑。检查self.instance.pk
是检查您是否正在创建或更新模型实例的典型方法。后一种方法似乎有效,谢谢!我唯一剩下的问题是,对于CreateView
(新软件包的表单),是默认的的初始值
没有设置为True
。我注意到在这种情况下,实际上,self.initial
是一个空字典,所以我可以对它进行特殊处理,但有没有更好的方法?get_initial_for_field
在我尝试它时,与CreateView
配合得很好,所以您只需要确保在方法中使用了正确的逻辑。检查self.instance.pk
是检查您是否正在创建或更新模型实例的典型方法。请注意,您的措辞“对于未绑定表单为真,对于绑定表单为真”没有真正的意义。初始数据仅用于未绑定的表单。也许您的意思是创建/更新实例。另一个选项是为您的UpdateView
覆盖get_initial()
。请注意,您的措辞“对于未绑定表单和绑定表单都是真的”没有真正的意义。初始数据仅用于未绑定的表单。也许您的意思是创建/更新实例。另一个选项是为您的UpdateView
覆盖get_initial()
。