Django:CreateView 增加字段?

6 投票
1 回答
10158 浏览
提问于 2025-04-17 13:16

我正在尝试编写一个Django的CreateView(类视图),这个视图是用用户的邮箱来代替用户ID,并根据邮箱来查找(或创建)用户。

我的模型没有什么特别的内容:

class Project(models.Model):
    name = models.CharField(_('Title'), max_length=100,)
    user = models.ForeignKey(User, verbose_name=_('user'),)
    ...

在我的forms.py中,我为表单添加了额外的邮箱字段:

class ProjectCreateForm(forms.ModelForm):
    email = forms.EmailField(required=True, )

    class Meta:
        model = Project
        fields = ('name', ...,)

在我的views.py中,我正在尝试判断用户是否存在,或者是否需要创建一个新用户。在这两种情况下,用户的ID都应该作为项目实例的一部分被保存。

class ProjectCreateDetails(CreateView):
    form_class = ProjectCreateForm
    template_name = '...'
    success_url = reverse_lazy('login') 
    model = Project

    def form_valid(self, form):
        try:
            user = User.objects.get(email=form.email)
        except User.DoesNotExist:
            user = User.objects.create_user(form.email, form.email, ''.join([random.choice(string.digits + string.letters) for i in range(0, 10)]))
            user.save()
        form.instance.user = user
        return super(ProjectCreateDetails, self).form_valid(form)

但是我遇到了一个错误,提示 'Solution'对象没有'email'这个属性

我需要把CreateView换成FormView吗?

1 个回答

9

你会看到错误信息 'Solution' object has no attribute 'email',这是因为 form.email 是无效的。经过验证的数据不会作为表单或模型表单的属性出现。当表单(包括模型表单)有效时,成功验证的数据会保存在一个叫 form.cleaned_data 的字典里。

另外,你不需要调用 user.save()。因为 create_user 已经把用户添加到数据库里了。你也不需要生成随机密码——如果 passwordNone,那么 create_user 会设置一个无法使用的密码。

最后,确保在 ProjectCreateForm 中不包含 user 字段。你可能没有包含,但你的代码写的是 fields = ('name', ...,),所以我不能确定。

把这些放在一起,你会得到以下(未经测试的)代码:

def form_valid(self, form):
    try:
        user = User.objects.get(email=form.cleaned_data['email'])
    except User.DoesNotExist:
        user = User.objects.create_user(form.cleaned_data['email'], form.cleaned_data['email']) 
    form.instance.user = user
    return super(ProjectCreateDetails, self).form_valid(form)

撰写回答