Как я могу улучшить это представление “регистрация” в Django?
-
21-08-2019 - |
Вопрос
У меня есть сайт на основе Django, который позволяет пользователям регистрироваться (но требует, чтобы администратор одобрил учетную запись, прежде чем они смогут просматривать определенные части сайта).Я основываю это на django.contrib.auth
.Я требую, чтобы пользователи регистрировались с адресом электронной почты от определенного доменного имени, поэтому я переопределил UserCreationForm
's save()
и 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()
.
Как правило, в Python считается плохой практикой, когда обработчик исключений в блоке try / except должен быть пустым.Другими словами, всегда фиксируйте конкретное исключение, такое как User.DoesNotExist
для этого случая.
Это также плохая практика - иметь много строк внутри try
часть блока try/except. часть блока try/except.Это лучшая форма для кодирования таким образом:
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 ...
Последняя, незначительная рекомендация - не отправлять электронное письмо непосредственно в вашем представлении, потому что это не будет масштабироваться, если ваш сайт начнет получать много запросов на регистрацию.Лучше добавить в django-почтовая программа приложение для выгрузки работы в очередь, обрабатываемую другим процессом.
Другие советы
Лично я стараюсь сначала использовать короткую ветвь инструкции if-else.Особенно, если он вернется.Это делается для того, чтобы избежать образования больших ветвей, где трудно разглядеть, что где заканчивается.Многие другие поступают так же, как вы, и оставляют комментарий к заявлению else.Но python не всегда имеет оператор end of block - например, если форма недействительна для вас.
Так, например:
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% вопросов "улучши мой код".
Есть ли что-то конкретное, чем вы недовольны?