问题
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