Django: CreateView with additional field?

无人久伴 提交于 2019-12-07 07:10:24

问题


I am trying to program a Django CreateView (CBV), which takes instead of the user id the user email and determines (or creates) the user based on the email.

My model does not contain anything special:

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

My forms.py adds the additional email field to the form:

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

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

In my views.py, I am trying to determine if the user exists or should be created. In both cases, the user id should be saved as part of the Project instance.

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)

However I am facing an error that the 'Solution' object has no attribute 'email'.

Do I need to switch to a FormView instead of a CreateView?


回答1:


You get the error 'Solution' object has no attribute 'email' because form.email is invalid. Validated data is never available as attributes of a form or model form. When forms (including model forms) are valid, the successfully validated data is available in the form.cleaned_data dictionary.

Note that you don't need to call user.save(). The create_user call has already added the user to the database. You don't have to generate a random password either -- if password is None, then create_user will set an unusable password.

Finally, make sure that you do not include the user field in the ProjectCreateForm. You probably do not, but your code says fields = ('name', ...,) so I can't tell for sure.

Put it together and you get the following (untested) code:

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)


来源:https://stackoverflow.com/questions/14420306/django-createview-with-additional-field

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!