用户表单和条件的服务器端预验证(设计/最佳实践)

时间:2015-11-24 22:30:10

标签: python validation sqlalchemy pyramid

问题:创建一个方法,用于在创建帐户时验证username是否存在,如果username存在则拒绝帐户,并建议用户创建新{{1}应该重复这个过程。

我根据我在这里阅读的一些STACKS问题(12)了解了如何执行此操作。比如:

  
      
  1. 将用户名发送到服务器。
  2.   
  3. 检查是否存在   数据库中的用户名。
  4.   
  5. 以真或假的方式回复客户   取决于用户名的存在。
  6.   
  7. 根据回复,发送   用户是客户端警报!
  8.   

我不确定如何使用金字塔 SQLAlchemy 在注册页面(也称为username页面)中正确执行该过程。由于我是新手,我想确保创建快速,高效且智能设计的代码。我想确保我保持最佳实践。

目前在Create an Account数据库中,UserUsername;这会导致系统在用户尝试创建db中存在的UNIQUE时崩溃。我的代码遗漏了一些东西,因为有一个追溯表明username任何帮助或建议真的很感激!如果我的方法很差,那么建议使用更好的方法!

软件:Python 2.7,Pyramid 1.5.7,SQLAlchemy 1.0.9

views.py
(代码:创建用户页面并保存新用户)

DETAIL:  Key (username)=(baseball) already exists.

追溯:

@view_config(route_name='create_user', request_method='GET', renderer='templates/create_account.jinja2')
def user_form_view(request):
    return {}

@view_config(route_name='save_new_user')
def save_new_user(request):
    with transaction.manager:

        username = request.params['username']

        check_username = api.retrieve_user(username) #retrieves one_user
        #check_users = api.retrieve_users() #this retrieves ALL the users

        taken = False
        for user in check_username: #prints out all user info
            if username == user.username:
                taken = True
                break
        if taken:
            username = request.params['username']

        password = request.params['password']
        firstname = request.params['firstname']
        lastname = request.params['lastname']
        email = request.params['email']

        new_user = api.create_user(username, password, firstname, lastname, email)
        new_account = api.update_group_add_user('Registered User', new_user)

        transaction.commit()
        return HTTPSeeOther(location=request.route_url('login'))

根据以下建议更新

问题:

我应该在registration_view管理函数之外创建函数validate_registration?这应该是IntegrityError: (raised as a result of Query-invoked autoflush; consider using a session.no_autoflush block if this flush is occurring prematurely) (psycopg2.IntegrityError) duplicate key value violates unique constraint "users_username_key" DETAIL: Key (username)=(baseball) already exists. [SQL: 'INSERT INTO users (username, firstname, lastname, email, password, institution, created_on) VALUES (%(username)s, %(firstname)s, %(lastname)s, %(email)s, %(password)s, %(institution)s, %(created_on)s) RETURNING users.id'] [parameters: {'username': u'baseball', 'firstname': u'jlo', 'lastname': u'lo', 'institution': None, 'created_on': datetime.datetime(2015, 11, 24, 22, 27, 20, 286260), 'password': '78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f', 'email': u'j'}] 声明吗?这是最好的方法吗? Boolean会在哪里存在?

使用GET和POST查看代码:

transaction.commit()

表格:

def validate_registration_form(request):
    with transaction.manager:
        username = request.params['username']
        check_username = api.retrieve_user(username)

        password = request.params['password']
        firstname = request.params['firstname']
        lastname = request.params['lastname']
        email = request.params['email']

        if check_username is not None:
            return False
        else:
            return True

@view_config(route_name='registration', renderer='templates/create_account.jinja2')
@view_config(route_name='save_registration',  renderer='templates/create_account.jinja2')
def registration_view(request):
    if request.method == 'GET':
        return {} # render the empty form
    elif request.method == 'POST':
        if validate_registration_form(request): #save new_user and redirect
            new_user = api.create_user(username, password, firstname, lastname, email)
            new_account = api.update_group_add_user('Registered User', new_user)
            transaction.commit()
            raise HTTPSeeOther(location=request.route_url('login'))
        else:
            # form is not valid, re-render the form
            # with the data user entered and an error message
            return {
                'error_message': 'username already taken',
                'username': request.POST.get('username', ''),
                'password': request.POST.get('password', ''),
                'firstname': request.POST.get('firstname', ''),
                'lastname': request.POST.get('lastname', ''),
                'email': request.POST.get('email', '')
                }

1 个答案:

答案 0 :(得分:1)

嗯,提交服务器端表单验证的经典方法是这样的(伪代码):

@view_config(route_name='registration', renderer='my_rego_form.jinja2')  # handles both GET and POST
def rego_form(request):
    if request.metod == 'GET':
        return {}  # render the empty form
    elif request.method == 'POST':
        if validate_rego_form(request):  
            # create a new user and redirect elsewhere
            create_user(request)
            raise HTTPFound('/post_registration_page') 
        else: 
            # form is not valid, re-render the form 
            # with the data user entered and an error message
            return {
                'error_message': 'Error creating user',
                'username': request.POST.get('username', '')
                'email': request.POST.get('email', '')
                'phone_num': request.POST.get('phone_num', '')
            }
        else:
            # some other HTTP method, not sure how to deal

因此,基本上,表单需要能够使用客户端提交的数据重新呈现自身。

验证方法本身可以是微不足道的,只需检查数据库中给定电子邮件的用户。或者,正如您尝试的那样,您可以尝试仅创建记录并处理异常,而不是预先验证。