我正在尝试开发一个网站,在输入用户凭据并成功验证Google reCaptcha后的注册流程中,用户必须被定向到一个页面,显示安全问题列表,用户必须回答一个成功注册网站的问题。
我的forms.py文件就在这里。
import re
from django import forms
from django.contrib.auth.forms import AuthenticationForm, PasswordResetForm, SetPasswordForm
from .models import CustomUser
from django.conf import settings
from django.utils.translation import ugettext as _
import urllib
import urllib.request as urllib2
import json
class SignUpForm(forms.ModelForm):
"""
A form that creates a user, with no privileges, from the given username and
password.
"""
password1= forms.CharField(label='Password',widget=forms.PasswordInput)
password2=forms.CharField(label='Confirm Password', widget=forms.PasswordInput)
class Meta:
#model to be used
model = CustomUser
#fields that have to be populated
fields=['username']
def __init__(self,*args,**kwargs):
self.request=kwargs.pop('requestObject',None)
super(SignUpForm,self).__init__(*args,**kwargs)
self.fields['username'].required=True
self.fields['password1'].required=True
self.fields['password2'].required=True
def clean(self):
super(SignUpForm,self).clean()
'''
Test the Google Recaptcha
'''
#url at which request will be sent
url='https://www.google.com/recaptcha/api/siteverify'
#dictionary of values to be sent for validation
values={
'secret': settings.GOOGLE_RECAPTCHA_SECRET_KEY,
'response': self.request.POST.get(u'g-recaptcha-response', None),
'remoteip': self.request.META.get("REMOTE_ADDR", None),
}
#making request
data=urlllib.parse.urlencode(values)
binary_data=data.encode('utf-8')
req= urllib.request.Request(url, binary_data)
response= urllib.request.urlopen(req)
result = json.loads(response.read().decode('utf-8'))
# result["success"] will be True on a success
if not result["success"]:
raise forms.ValidationError("Only humans are allowed to submit this form.")
return self.cleaned_data
def clean_password2(self):
#checking whether the passwords match or not
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):
#overriding the default save method for ModelForm
user = super(UserCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
models.py文件在这里
from django.db import models
from django.conf import settings
from django.contrib.auth.models import AbstractUser
# Create your models here.
#Choices of questions
SECRET_QUESTION_CHOICES = (
('WCPM', "In which city did your parents meet?"),
('WCN', "What was your childhood nickname?"),
('WPN', "What is your pet's name?"),
)
#Secret Questions
class SecretQuestion(models.Model):
id=models.AutoField(primary_key=True)
secret_question = models.CharField(max_length = 100, choices = SECRET_QUESTION_CHOICES, default = SECRET_QUESTION_CHOICES[0],null=False, blank=False)
class Meta:
db_table='Security Questions'
class CustomUser(AbstractUser):
profile_pic = models.ImageField(upload_to = 'profile_pics/', blank = True, null = True)
following = models.ManyToManyField('self', symmetrical = False, related_name = 'followers', blank = True)
ques_followed = models.ManyToManyField('question.Question', related_name = 'questions_followed', blank = True)
topic_followed = models.ManyToManyField('topic.Topic', related_name = 'topic_followed', blank = True)
security_questions = models.ManyToManyField(SecretQuestion, related_name = 'secret_question_user', through = "SecretQuestionAnswer")
class Meta:
db_table = 'User'
def __str__(self):
return self.username
class SecretQuestionAnswer(models.Model):
user = models.ForeignKey(CustomUser)
secret_question = models.ForeignKey(SecretQuestion)
answer = models.CharField(max_length = 100,blank=False, null=False)
class Meta:
db_table='SecretQuestionAnswer'
现在,在成功提交SignUpForm之后,如果用户成功回答了上述问题之一,则只应注册用户(保存在数据库中)。 应该如何处理这个问题?请帮忙。
过去两天我一直在试着解决这个问题。
有人可以提供帮助。
答案 0 :(得分:1)
Normaly你需要有一个布尔字段,表明用户是否完成所有步骤。默认情况下,此字段为False
,准备就绪时将其设置为True
。仅当字段设置为True
时才允许登录。
另一种方法是使用向导http://django-formtools.readthedocs.org/en/latest/。使用这种方法,您需要以某种方式保护用户的密码,因为留在会话中不是一个好主意。