我们使用django构建了我们的平台,并为我们的使用创建了一个自定义用户模型。
到目前为止,我们的平台仅被邀请,现在我们想向所有人开放邀请。
我已经修改了我们的自定义表单和用户注册视图,一切正常,但我们面临一个问题。当用户的电子邮件未在我们的平台上注册时发送邀请时,我们为他创建一个新用户并设置一个布尔值以将其标记为未激活。当收到邀请时,一切正常,但如果用户直接进入我们的页面并打开注册表单,我们就会收到错误信息,即已存在此电子邮件的用户。
我们正在扩展CreateView和UserCreationForm以实现我们的自定义注册表单,因此我猜测我必须覆盖这些类中的一种方法,但不太确定哪一种,我已经尝试使用UserCreationForm的save方法,但它似乎不起作用,它会弹出错误消息而不进入该方法。
关于我如何做到这一点的任何想法?所需的实现将是我们查看具有该电子邮件的用户是否存在并且他处于非活动状态然后保存注册表单元素并将其设置为活动,否则只显示错误消息。
class CustomUserCreationForm(UserCreationForm):
"""A form for creating new users. Includes all the required
fields, plus a repeated password."""
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
def __init__(self, *args, **kwargs):
super(CustomUserCreationForm, self).__init__(*args,**kwargs)
self.fields.pop('username')
class Meta:
model = DealCircleUser
#fields = ('email', 'dob', 'first_name', 'last_name')
fields = ('email', 'first_name', 'last_name')
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError ("Passwords don't match")
return password2
def save(self, commit=True):
exits = DealCircleUser.objects.filter(email=self.cleaned_data["email"]).exists()
if exits:
print('We have the user')
user = DealCircleUser.objects.get(email=self.cleaned_data["email"])
else:
print('No user found')
# Save the provided password in hashed format
user = super(UserCreationForm, self).save(commit=False)
#check if there is a user already created with this
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
观点是:
类RegisterUserView(CreateView): model = DealCircleUser template_name =' register.html' form_class = CustomUserCreationForm success_url = reverse_lazy(' frontend_profile') 邀请=无
def get_form(self, form_class):
code = self.request.GET.get('code')
if code:
self.invitation = Invitation.validate_code(code)
if not self.request.user.is_anonymous():
form_class = InputEmailForm
self.object = self.request.user
form = super(RegisterUserView, self).get_form(form_class)
form.fields['email'].widget.attrs['class'] = 'form-control'
if self.request.user.is_anonymous():
if self.invitation and self.invitation.email:
form.fields['email'].widget.attrs['readonly'] = True
form.fields['first_name'].widget.attrs['class'] = 'form-control'
form.fields['last_name'].widget.attrs['class'] = 'form-control'
form.fields['password1'].widget.attrs['class'] = 'form-control'
form.fields['password2'].widget.attrs['class'] = 'form-control'
if self.invitation:
form.initial['email'] = self.invitation.email
return form
def get_context_data(self, **kwargs):
ret = super(RegisterUserView, self).get_context_data(**kwargs)
ret['twitterEnabled'] = settings.ENABLE_TWITTER
if self.request.user.is_anonymous():
#if not self.invitation or self.invitation.is_used():
# ret['invalid_code'] = True
# return ret
if self.invitation and self.invitation.is_used():
ret['invalid_code'] = True
return ret
ret['code'] = self.request.GET.get('code')
return ret
def form_valid(self, form):
ret = super(RegisterUserView, self).form_valid(form)
if type(ret) == HttpResponseRedirect:
if self.invitation:
self.invitation.status = Invitation.STATUS_REGISTERED
self.invitation.save()
messages.add_message(self.request, messages.SUCCESS,
_('Your account has been created. Welcome to DealCircle!'))
else:
messages.add_message(self.request, messages.SUCCESS, _('Your account has been updated successfully.'))
user = authenticate(email=form.cleaned_data.get('email'), password=form.cleaned_data.get('password1'))
if user and user.is_active:
login(self.request, user)
return ret
def get_success_url(self):
if self.invitation and self.invitation.deal:
return reverse('frontend_invitation_response', args=(self.invitation.code,))
else:
return reverse('frontend_profile')
def linkedin_info(user):
import oauth2 as oauth
consumer = oauth.Consumer(settings.SOCIAL_AUTH_LINKEDIN_KEY, settings.SOCIAL_AUTH_LINKEDIN_SECRET)
access_token = oauth.Token(key=user.linkedin_token, secret=user.linkedin_token_secret)
client = oauth.Client(consumer, access_token)
resp, content = client.request("http://api.linkedin.com/v1/people/~:(first-name,last-name,phone-numbers,picture-urls::(original))?format=json", "GET", "")
return resp, content
自定义用户管理器是:
class DealCircleUserManager(BaseUserManager):
def create_user(self, email=None, password=None, **extra_fields):
now = timezone.now()
if not email:
raise ValueError('The given email must be set')
email = UserManager.normalize_email(email)
user = self.model(email=email,
is_staff=False, is_active=True, is_superuser=False,
last_login=now, date_joined=now, **extra_fields)
user.set_password(password)
user.save(using=self._db)
from postman.models import AddressBook
AddressBook.objects.get_or_create(user=user)
return user
def create_superuser(self, email, password, **extra_fields):
u = self.create_user(email, password, **extra_fields)
u.is_staff = True
u.is_active = True
u.is_superuser = True
u.save(using=self._db)
from postman.models import AddressBook
AddressBook.objects.get_or_create(user=u)
return u
模型是这样的:
class DealCircleUser(AbstractBaseUser, PermissionsMixin):
USERNAME_FIELD = 'email'
AVATAR_STORAGE_URL = 'https://%s.s3.amazonaws.com/%s'
avatar = models.ImageField(storage=s3, upload_to="users", null=True, blank=True)
avatar_thumb = ImageSpecField(cachefile_storage=s3, source='avatar',
processors=[ResizeToFill(*settings.THUMB_AVATAR)],
format='JPEG',
options={'quality': 60})
avatar_square_thumb = ImageSpecField(cachefile_storage=s3, source='avatar',
processors=[SmartResize(*settings.THUMB_AVATAR_SQUARE)],
format='JPEG',
options={'quality': 60})
email = models.EmailField(max_length=254, unique=True)
address = models.CharField(max_length=254, blank=True)
postal_code = models.CharField(max_length=100, blank=True)
city = models.CharField(max_length=254, blank=True)
country = models.ForeignKey(Country, verbose_name='country', null=True, blank=True)
phone = models.CharField(max_length=30, blank=True)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
dob = models.DateField(null=True, blank=True)
bio = models.TextField(blank=True)
twitter_token = models.CharField(max_length=100, null=True, blank=True)
twitter_token_secret = models.CharField(max_length=100, null=True, blank=True)
linkedin_token = models.CharField(max_length=100, null=True, blank=True)
linkedin_token_secret = models.CharField(max_length=100, null=True, blank=True)
linkedin_connection_hash = models.CharField(max_length=64, blank=True)
google_access_token = jsonfield.JSONField(null=True, blank=True)
google_user_extras = jsonfield.JSONField(null=True, blank=True)
company = models.ForeignKey(Company, verbose_name='company', blank=True, null=True)
date_joined = models.DateField(null=True)
first_visit = models.BooleanField(default=True)
is_staff = models.BooleanField(_('staff status'), default=False,
help_text=_('Designates whether the user can log into this admin '
'site.'))
is_active = models.BooleanField(_('active'), default=True,
help_text=_('Designates whether this user should be treated as '
'active. Unselect this instead of deleting accounts.'))
objects = DealCircleUserManager()
def get_avatar_from_url(self, url):
try:
self.avatar.save(os.path.basename(url), ContentFile(urllib2.urlopen(url).read()))
self.save()
return True
except Exception, e:
return False
def get_avatar_url(self):
return self.AVATAR_STORAGE_URL % (settings.BOTO_S3_BUCKET, self.avatar)
def get_full_name(self):
full_name = '%s %s' % (self.first_name, self.last_name)
return full_name.strip()
def get_short_name(self):
return self.first_name
def get_dealinvestor(self, deal):
return self.dealinvestor_set.get(deal=deal)
def is_email_valid(self):
try:
validate_email(self.email)
return True
except:
return False
def disable_first_visit(self):
self.first_visit = False
self.save()
答案 0 :(得分:0)
我认为您的表单无法验证: 你应该看看UserCreationForm的干净方法,然后做这样的事情(没有经过测试):
def clean_email(self):
"""
First checking if the there is an invited user (User with same email exists and active==False ), if so validate the email.
If the user exists and is active that means that the email is already in use, we raise a ValidationError
If none of the above are True, the user does not exists at all, we should create it.
"""
email = self.cleaned_data['email']
if DealCircleUser.objects.filter(email=self.cleaned_data["email"], active=False).exists():
return email
elif DealCircleUser.objects.filter(email=self.cleaned_data["email"], active=True).exists():
raise forms.ValidationError(u'Email "%s" is already in use.' % email)
return email