创建时自动更新模型字段

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)