Python 未接受邀请的用户也已注册

Python 未接受邀请的用户也已注册,python,django,django-models,django-forms,django-allauth,Python,Django,Django Models,Django Forms,Django Allauth,我的应用程序中的功能是用户应首先请求邀请,如果管理员(来自管理员)接受了他的邀请,则应发送一条消息,您可以注册 特征流 用户提交带有其电子邮件地址的表单,并将发送邮件表示感谢。现在,如果管理员接受他/她的请求,即请求_accepted现在将为真,并将发送一封邮件,告知您现在可以注册。最后,当用户进入注册页面并提交表单时,应该检查他在注册期间填写并提交的电子邮件是否已被接受。如果接受,则注册成功,否则显示错误,说明此电子邮件地址未被邀请 class Invitation(models.Model)

我的应用程序中的功能是用户应首先请求邀请,如果管理员(来自管理员)接受了他的邀请,则应发送一条消息,您可以注册

特征流

用户提交带有其电子邮件地址的表单,并将发送邮件表示感谢。现在,如果管理员接受他/她的请求,即请求_accepted现在将为真,并将发送一封邮件,告知您现在可以注册。最后,当用户进入注册页面并提交表单时,应该检查他在注册期间填写并提交的电子邮件是否已被接受。如果接受,则注册成功,否则显示错误,说明此电子邮件地址未被邀请

class Invitation(models.Model):
    email = models.EmailField(unique=True, verbose_name=_("e-mail Address"))
    request_approved = models.BooleanField(default=False, verbose_name=_('request accepted'))

@receiver(post_save, sender=Invitation)
def send_email_when_invite_is_accepted_by_admin(sender, instance, *args, **kwargs):
    request_approved = instance.request_approved
    if request_approved:
        subject = "Request Approved"
        message = "Hello {0}! Your request has been approved. You can now signup".format(instance.email)
        from_email = None
        to_email = [instance.email]
        send_mail(subject, message, from_email, to_email, fail_silently=True)

def requestInvitation(request):
    form = InviteForm(request.POST or None)
    if form.is_valid():
        join = form.save(commit=False)
        email = form.cleaned_data.get('email')
        already_join, created = Invitation.objects.get_or_create(email=email)
        if created:
            already_join.save()
            subject = "Thank you for your request to sign up our community"
            message = "Welcome! We will be in contact with you."
            from_email = None
            to_email = [email]
            send_mail(subject, message, from_email, to_email, fail_silently=True)
            messages.success(request, '{0} has been invited'.format(email))
        return HttpResponseRedirect("/")
    context = {"form": form}
    return render(request, 'home.html', context)


ACCOUNT_SIGNUP_FORM_CLASS = 'pages.custom_sign_up_form.CustomSignupForm'
自定义\注册\表单.py

from invitation.models import Invitation

class CustomSignupForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(CustomSignupForm, self).__init__(*args, **kwargs)

    def clean_email(self):
        value = self.cleaned_data.get('email')
        print ('value before adapter', value)
        value = get_adapter().clean_email(value)
        print ('value', value)
        if value and app_settings.UNIQUE_EMAIL:
            value = self.validate_unique_email(value)
        try:
            Invitation.objects.get(email=value, request_approved=True)
        except Invitation.DoesNotExist:
            raise forms.ValidationError(errors['Sorry! you are not yet invited'])
        return value

    def signup(self, request, user):
      user.save()
我这样做的方式也允许注册不被接受的用户

更新

如果我把clean_电子邮件逻辑放在注册中

def signup(self, request, user):
      print ('request', request, user)
      value = self.cleaned_data.get('email')
      print ('email is', value)
      try:
          Invitation.objects.get(email=value, request_approved=True)
      except:
          raise forms.ValidationError(errors['sorry! You are not yet invited'])
      user.save()
我得到“未定义名称错误”


根据问题的更新部分: 这里出了很大的问题。你是说你有一个
对不起!您将…
作为
,并希望它返回一个值

这是您试图访问的内容:

errors = {
    'sorry! you are not yet invited': None,
}
像这样带有感叹号、空格等的键是无效的

请注意,
error
没有在方法中定义(在类中我看不到的任何地方)。如果已初始化为
变量,则应使用
self
访问该变量

如果尚未使用默认错误消息声明错误dict,则应将其创建为类变量

class CustomerSignupForm(forms.Form):
    errors = {
        'not_invited': "Sorry! You are not yet invited.",
    }
现在,在注册方法中,您可以访问错误消息:

raise forms.ValidationError(
    self.errors['not_invited'],
    code='not_invited'
)

根据原始问题: 我现在不是100%确定问题出在哪里。但有几件事你可以看一看并改进

第1点:变量名应该清楚地解释它包含的内容。即

value = self.cleaned_data.get('email')
是一个包含电子邮件字符串或无电子邮件字符串的字段。保持简单明了,并将
电子邮件
作为变量名。如果逻辑中的值发生变化,可以将其重命名为新名称,以清楚地解释变量的内容<代码>值是一个太宽泛的名称,非常容易混淆

 value = get_adapter().clean_email(value)
这里发生了什么?定义值(又是坏名字)后有一个打印,它返回什么?你期望它做什么

第2点:将验证保留在
干净的
方法中
您的
尝试
使用
验证错误的
除外
应该在表单清理方法中。如果它不适合正在清理的某个字段,则应重写
clean
方法,运行
super
的clean方法,并添加验证所需内容的自定义方法

第3点:注册方法。 我还没有看到一个地方可以调用
signup
方法。它不是从
表单继承的。表单
,因此据我所知,它还没有被调用


注意:我不会为这个主题创建任何新的答案,我会更新这个“答案”。

感谢您的精彩解释。它工作了,但是错误没有显示在页面上。原因可能是什么?@pythonLover不太清楚,但我已经更新了我的答案。有几件事你可以看一看并改进。除了“我的clean_电子邮件”功能中的命名问题之外,验证过程对吗?如果它没有达到你期望的效果,那就不对了。您可能有一个视图,其中使用
表单处理
CustomSignupForm
。调用是否有效。将该来源添加到问题中。您在答案中发布的第一次更新有效,但只有错误消息未显示在前端,并表示抱歉!如果电子邮件不存在或未被接受,您尚未被邀请。但对于第二种方法,即扩展SignupForm类,我得到了一个错误django.core.exceptions.impropertlyconfigured:导入表单类页面时出错。自定义\注册\表单:“无法导入名称‘BaseSignupForm’”。关于第二个问题,我想我必须提出一个新问题。
 value = get_adapter().clean_email(value)