简体   繁体   中英

Django: CreateView with additional field?

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?

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM