Django: CreateView with custom field?

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

My model doesn't 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 an extra 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'm trying to determine if a user exists or should be created. In both cases, the user ID must 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 ran into the error that 'Solution' object has no attribute 'email'

.

Do I need to switch to FormView instead of CreateView?

+3


source to share


1 answer


You will get an error 'Solution' object has no attribute 'email'

because it is form.email

invalid. Validated data is never available as shape attributes or model shape. When the forms (including model forms) are valid, the successfully validated data is available in the dictionary form.cleaned_data

.

Note that you don't need to call user.save()

. The call create_user

has already added the user to the database. You also don't need to generate a random password - if password

- None

will create_user

set an inappropriate password.

Finally, make sure you don't include the field user

in ProjectCreateForm

. You probably won't, but your code speaks fields = ('name', ...,)

, so I can't tell for sure.



Put it together and you end up with 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)

      

+5


source







All Articles