Como posso melhorar este ponto de vista “registrar” no Django?
-
21-08-2019 - |
Pergunta
Eu tenho um site baseado em Django que permite aos usuários registrar (mas requer um administrador para aprovar a conta antes que eles possam ver certas partes do site). Estou baseando-off de django.contrib.auth
. Eu exigir que os usuários se registrar com um endereço de e-mail a partir de um determinado nome de domínio, então eu tenho substituído métodos UserCreationForm
e save()
do clean_email()
.
A minha página de registo usa a seguinte vista. Eu estou interessado em ouvir sobre como eu poderia melhorar esta melhorias vista de código ou melhorias de processo (ou qualquer outra coisa, realmente).
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)
)
Solução
Você não precisa mesmo este código, mas acho que o estilo:
pk = None
try: pk = User.objects.filter(username=username)[0].pk
except: pass
é mais naturalmente escrito assim:
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
user = None
e, em seguida, o administrador notificar {{ user.id }}
uso modelo em vez de {{ pk }}
.
Mas, como eu disse, você não precisa que o código em tudo, porque você já tem um objeto de usuário a partir de sua chamada para authenticate()
.
Geralmente, em Python, é considerado má prática para ter o manipulador de exceção em um try / exceto bloco vazio. Em outras palavras, sempre capturar uma exceção específica, como User.DoesNotExist
para este caso.
Também é má prática ter muitas linhas dentro da parte try
do try / exceto bloco. É melhor forma de código desta maneira:
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 ...
A final, menor, a recomendação é a de não enviar o e-mail diretamente na sua opinião, porque isso não vai escalar se o site começa a ver pedidos de registro pesados. É melhor add no django-mailer aplicativo para descarregar o trabalho em uma fila tratado por um outro processo.
Outras dicas
Eu, pessoalmente, tentar colocar o ramo curto de uma instrução if-else em primeiro lugar. Especialmente se ele retorna. Isto para evitar grandes ramos onde a sua difícil ver o que termina onde. Muitos outros fazem, como você tem feito e colocar um comentário na instrução else. Mas python does not sempre tem um final de declaração bloco - como se um formulário não é válido para você.
Assim, por exemplo:
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)
)
...
Primeira resposta:. Parece um pedaço de um monte melhor do que 95% das perguntas "melhorar o meu código"
Existe alguma coisa em particular que você está insatisfeito com?