创建时自动更新模型字段
Automatically updating a model field when it is created
我想在创建模型字段时自动更新它。这就是我的情况。我有一个自定义用户模型,我的客户可以使用它来登录。登录后,他们将转到 account/profile 页面,该页面有一个 link 表单。目前,当用户提交表单时,它会创建一个 LevelTest
模型的实例(这是我网站正常工作所需要的)。这是表单的视图 class:
class LevelTestView(generic.CreateView):
template_name = "leads/leveltest.html"
form_class = LevelTestModelForm
def get_success_url(self):
return reverse("profile-page")
这是 LevelTestModelForm:
class LevelTestModelForm(forms.ModelForm):
class Meta:
model = LevelTest
fields = (
'first_name',
'last_name',
'age',
'username',
)
我要自动填写的是用户名字段。事实上,我希望当用户输入时它甚至不显示在表单本身上。username
是用户模型中的一个字段,所以我只想填充新的 LevelTest 的 username
字段in 与当前用户的用户名。因此,我使用了如下所示的 post_save 信号(不起作用):
def post_leveltest_created_signal(sender, instance, created, **kwargs):
if created:
instance.objects.update(
username=instance.user.username,
description='Add Description',
phone_number=instance.user.cellphone,
email=instance.user.username,
)
post_save.connect(post_leveltest_created_signal, sender=LevelTest)
希望大家帮我修改post_save信号,这样当用户创建LevelTest实例时,LevelTest的用户名字段(以及phone_number和电子邮件)被填充与用户模型的信息。非常感谢!
如果我理解你是对的,你不需要使用信号,你可以更容易地保存用户名:
在您的 CreateView 中扩展 get_form_kwargs
方法,就像这样:
class LevelTestView:(generic.CreateView)
...
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
扩展 Form
中的 __init__
和 save
方法,像这样:
class LevelTestModelForm(forms.ModelForm):
...
def __init__(self, user, *args, **kwargs):
self.user = user
super().__init__(*args, **kwargs)
...
def save(self, commit=True):
leveltest = super().save(commit=False)
# I think it would be better if you saved only 'user' instance
# like this - leveltest.user = self.user (of course if you have fk to user model)
leveltest.username = self.user.username
leveltest.phone_number=self.user.cellphone
leveltest.email=self.user.username
leveltest.save()
return leveltest
我认为@KIN1991 的回答非常棒,但是您可以 minimize/optimize 通过重写 form_valid
方法来进一步编写代码。像这样:
class LevelTestView:(generic.CreateView)
...
def form_valid(self, form, *args, **kwargs):
user = self.request.user
form.instance.username = user.username
form.instance.phone_number=user.cellphone,
form.instance.email=user.username
return super().form_valid(form, *args, **kwargs)
我想在创建模型字段时自动更新它。这就是我的情况。我有一个自定义用户模型,我的客户可以使用它来登录。登录后,他们将转到 account/profile 页面,该页面有一个 link 表单。目前,当用户提交表单时,它会创建一个 LevelTest
模型的实例(这是我网站正常工作所需要的)。这是表单的视图 class:
class LevelTestView(generic.CreateView):
template_name = "leads/leveltest.html"
form_class = LevelTestModelForm
def get_success_url(self):
return reverse("profile-page")
这是 LevelTestModelForm:
class LevelTestModelForm(forms.ModelForm):
class Meta:
model = LevelTest
fields = (
'first_name',
'last_name',
'age',
'username',
)
我要自动填写的是用户名字段。事实上,我希望当用户输入时它甚至不显示在表单本身上。username
是用户模型中的一个字段,所以我只想填充新的 LevelTest 的 username
字段in 与当前用户的用户名。因此,我使用了如下所示的 post_save 信号(不起作用):
def post_leveltest_created_signal(sender, instance, created, **kwargs):
if created:
instance.objects.update(
username=instance.user.username,
description='Add Description',
phone_number=instance.user.cellphone,
email=instance.user.username,
)
post_save.connect(post_leveltest_created_signal, sender=LevelTest)
希望大家帮我修改post_save信号,这样当用户创建LevelTest实例时,LevelTest的用户名字段(以及phone_number和电子邮件)被填充与用户模型的信息。非常感谢!
如果我理解你是对的,你不需要使用信号,你可以更容易地保存用户名:
在您的 CreateView 中扩展 get_form_kwargs
方法,就像这样:
class LevelTestView:(generic.CreateView)
...
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
扩展 Form
中的 __init__
和 save
方法,像这样:
class LevelTestModelForm(forms.ModelForm):
...
def __init__(self, user, *args, **kwargs):
self.user = user
super().__init__(*args, **kwargs)
...
def save(self, commit=True):
leveltest = super().save(commit=False)
# I think it would be better if you saved only 'user' instance
# like this - leveltest.user = self.user (of course if you have fk to user model)
leveltest.username = self.user.username
leveltest.phone_number=self.user.cellphone
leveltest.email=self.user.username
leveltest.save()
return leveltest
我认为@KIN1991 的回答非常棒,但是您可以 minimize/optimize 通过重写 form_valid
方法来进一步编写代码。像这样:
class LevelTestView:(generic.CreateView)
...
def form_valid(self, form, *args, **kwargs):
user = self.request.user
form.instance.username = user.username
form.instance.phone_number=user.cellphone,
form.instance.email=user.username
return super().form_valid(form, *args, **kwargs)