繁体   English   中英

如何改进 Django 中的“注册”视图?

[英]How can I improve this “register” view in Django?

我有一个基于 Django 的站点,允许用户注册(但需要管理员批准该帐户才能查看站点的某些部分)。 我基于django.contrib.auth 我要求用户使用某个域名的 email 地址进行注册,因此我覆盖了UserCreationFormsave()clean_email()方法。

我的注册页面使用以下视图。 我有兴趣了解如何改进这个视图——代码改进或流程改进(或其他任何东西,真的)。

def register(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)

        if form.is_valid():
            message = None

            form.save()

            username = form.cleaned_data['username']
            password = form.cleaned_data['password1']

            user = authenticate(username=username, password=password)

            first_name = form.cleaned_data['first_name']
            last_name = form.cleaned_data['last_name']
            email = user.email

            # If valid new user account
            if (user is not None) and (user.is_active):
                login(request, user)
                message = "<strong>Congratulations!</strong> You have been registered."

                # Send emails
                try:
                    # Admin email
                    pk = None
                    try: pk = User.objects.filter(username=username)[0].pk
                    except: pass

                    admin_email_template = loader.get_template('accounts/email_notify_admin_of_registration.txt')
                    admin_email_context = Context({
                        'first_name': first_name,
                        'last_name': last_name,
                        'username': username,
                        'email': email,
                        'pk': pk,
                    })
                    admin_email_body = admin_email_template.render(admin_email_context)
                    mail_admins("New User Registration", admin_email_body)

                    # User email
                    user_email_template = loader.get_template('accounts/email_registration_success.txt')
                    user_email_context = Context({
                        'first_name': form.cleaned_data['first_name'],
                        'username': username,
                        'password': password,
                    })
                    user_email_body = user_email_template.render(user_email_context)
                    user.email_user("Successfully Registered at example.com", user_email_body)
                except:
                    message = "There was an error sending you the confirmation email. You should still be able to login normally."
            else:
                message = "There was an error automatically logging you in. Try <a href=\"/login/\">logging in</a> manually."

            # Display success page
            return render_to_response('accounts/register_success.html', {
                    'username': username,
                    'message': message,
                },
                context_instance=RequestContext(request)
            )
    else: # If not POST
        form = UserCreationForm()

    return render_to_response('accounts/register.html', {
            'form': form,
        },
        context_instance=RequestContext(request)
    )

你甚至不需要这段代码,但我认为风格:

pk = None
try: pk = User.objects.filter(username=username)[0].pk
except: pass

更自然地写成:

try:
    user = User.objects.get(username=username)
except User.DoesNotExist:
    user = None

然后在您的管理员通知模板中使用{{ user.id }}而不是{{ pk }}

但是,就像我说的那样,您根本不需要该代码,因为您已经通过调用authenticate()获得了用户 object 。

通常在 Python 中,将 try/except 块中的异常处理程序设为空被认为是不好的做法。 换句话说,对于这种情况,始终捕获特定异常,例如User.DoesNotExist

在 try/except 块的try部分中有很多行也是不好的做法。 以这种方式编码是更好的形式:

try:
    ... a line of code that can generate exceptions to be handled ...
except SomeException:
    ... handle this particular exception ...
else:
    ... the rest of the code to execute if there were no exceptions ...

最后的次要建议是不要在您的视图中直接发送 email,因为如果您的站点开始看到大量注册请求,这将无法扩展。 最好在django-mailer应用程序中添加以将工作卸载到由另一个进程处理的队列中。

我个人尝试将 if-else 语句的短分支放在首位。 特别是如果它返回。 这是为了避免在难以看到什么结束的地方获得大分支。 许多其他人确实像您所做的那样,并在 else 语句中发表评论。 但是 python 并不总是有块语句的结尾 - 就像表单对您无效一样。

例如:

def register(request):
    if request.method != 'POST':
       form = UserCreationForm()
       return render_to_response('accounts/register.html', 
                                 { 'form': form, },
                                 context_instance=RequestContext(request)
                                 )

    form = UserCreationForm(request.POST)
    if not form.is_valid():
       return render_to_response('accounts/register.html', 
                                 { 'form': form, },
                                 context_instance=RequestContext(request)
                                 )
    ...

第一反应:它看起来比 95% 的“改进我的代码”问题要好得多。

你有什么特别不满意的地方吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM