只有在安全问题得到解答后,才能将用户保存在数据库中(使用ModelForm)?

时间:2015-12-04 20:56:05

标签: python django django-models django-forms

我正在尝试开发一个网站,在输入用户凭据并成功验证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之后,如果用户成功回答了上述问题之一,则只应注册用户(保存在数据库中)。 应该如何处理这个问题?请帮忙。

过去两天我一直在试着解决这个问题。

有人可以提供帮助。

1 个答案:

答案 0 :(得分:1)

Normaly你需要有一个布尔字段,表明用户是否完成所有步骤。默认情况下,此字段为False,准备就绪时将其设置为True。仅当字段设置为True时才允许登录。

另一种方法是使用向导http://django-formtools.readthedocs.org/en/latest/。使用这种方法,您需要以某种方式保护用户的密码,因为留在会话中不是一个好主意。