Comments 11
Кстати, метод get_cookies можно упростить:
Спасибо Dreadatour!
Принцип с else общий — если в конце блока if есть return, то всё то, что должно выполняться в случае, если условие if не расценивается как истинное, можно помещать не в блок else, а просто размещать сразу после блока if, без каких-либо блоков — потому что если условие if было расценено как истинное, то всё, что ниже, всё равно уже никогда не выполнится (даже если было вызвано исключение).
def get_cookies(self, request):
if request is None:
return {}
return {key: 'secret' for key in request.COOKIES}
Спасибо Dreadatour!
Принцип с else общий — если в конце блока if есть return, то всё то, что должно выполняться в случае, если условие if не расценивается как истинное, можно помещать не в блок else, а просто размещать сразу после блока if, без каких-либо блоков — потому что если условие if было расценено как истинное, то всё, что ниже, всё равно уже никогда не выполнится (даже если было вызвано исключение).
+1
Мне, кажется, это только наоборот усложняет восприятие программы. Конструкция if-else-then визуально воспринимается проще и логика более простая, чем в «упрощённом» варианте.
0
Просто представьте, что у вас не одно условие для return, а хотя бы три, что бывает довольно часто.
0
KISS
+1
За пост спасибо!
Но при авторизации скрытие email грозит, тем что можно долго искать проблему с дублированием email в другом регистре, что по де-фолту для джанги актуально. Во-первых, в стандартной модели пользователя email не уникальный. Во-вторых в стандратном поле EmailField нормализируется только домен. Таким образом, если вы все использовали из коробки и при регистрации сами не валидилировали email на уникальность с учетом возможного использования разного регистра символов то в зависимости от вашего бэкэнда утентификации при авторизации могут быть ошибки из-за того что в базе есть разные пользователи с адресами aruseni.magiku@gmail.com и Aruseni.Magiku@gmail.com. На рабочем сайте с большой базой пользователей вы можете долго искать эту проблему. Знание же для какого именно пользователя проблема актуальна в данном случае позволяет установить ее причину гораздо быстрее.
Но при авторизации скрытие email грозит, тем что можно долго искать проблему с дублированием email в другом регистре, что по де-фолту для джанги актуально. Во-первых, в стандартной модели пользователя email не уникальный. Во-вторых в стандратном поле EmailField нормализируется только домен. Таким образом, если вы все использовали из коробки и при регистрации сами не валидилировали email на уникальность с учетом возможного использования разного регистра символов то в зависимости от вашего бэкэнда утентификации при авторизации могут быть ошибки из-за того что в базе есть разные пользователи с адресами aruseni.magiku@gmail.com и Aruseni.Magiku@gmail.com. На рабочем сайте с большой базой пользователей вы можете долго искать эту проблему. Знание же для какого именно пользователя проблема актуальна в данном случае позволяет установить ее причину гораздо быстрее.
+1
Спасибо, что подняли данную тему. Такая проблема действительно существует, если специально не позаботиться об обработке адресов электронной почты, набранных с использованием букв в разном регистре.
Реально регистрация может быть, например, такой (обработка IntegrityError тут для маловероятной ситуации race condition в случае одновременной регистрации двух пользователей):
К счастью, в Django 1.5 обязательность танцев с бубном заметно уменьшится в связи с появлением определяемых разработчиком моделей User.
Реально регистрация может быть, например, такой (обработка IntegrityError тут для маловероятной ситуации race condition в случае одновременной регистрации двух пользователей):
Скрытый текст
Форма регистрации с её родительским классом:
Соответственно, в бэкэнде авторизации просто позволяем пользователю вводить email с использованием букв любого регистра:
if request.method == "POST":
form = RegistrationForm(request.POST, request.FILES)
if form.is_valid():
email = form.cleaned_data["email"].lower()
password = form.cleaned_data["password"]
try:
user = User.objects.create_user(hashlib.sha1(email).hexdigest()[:30],
email,
password)
user.username = "".join(["user", str(user.id)])
user.save()
except IntegrityError:
messages.error(request, u"При регистрации возникла ошибка. Пожалуйста, попробуйте ещё раз.")
try:
# Rollback the transaction (otherwise a DatabaseError would be raised when trying to delete the user)
connection._rollback()
# In case the IntegrityError was raised when renaming the user
user.delete()
# UnboundLocalError can be raised if the user variable is not defined
except UnboundLocalError:
pass
return HttpResponseRedirect(reverse('dating.views.index'))
UserProfile.objects.create(user=user,
name=form.cleaned_data["name"],
photo=form.cleaned_data["photo"])
user = authenticate(username=user.username, password=password)
login(request, user)
email_body = render_to_string('registration_email.txt', {
"username": form.cleaned_data["name"], "user_id": user.id
})
send_mail('Background Dating',
email_body,
None,
[email],
fail_silently=True)
return HttpResponseRedirect(reverse('dating.views.index'))
else:
form = RegistrationForm()
return render_to_response('index.html',
{"registration_form": form},
context_instance=RequestContext(request))
Форма регистрации с её родительским классом:
class UserProfileForm(forms.ModelForm):
def clean_photo(self):
image = self.cleaned_data.get('photo')
if image:
if not "." in image.name:
raise ValidationError(u"Пожалуйста, убедитесь, что файл имеет расширение.")
extension = image.name.rsplit('.',1)[1].lower()
if extension not in ["jpg", "jpeg", "gif", "png"]:
raise ValidationError(u"Пожалуйста, убедитесь, что изображение имеет одно из следующих расширений: jpg, jpeg, png, gif.")
if image._size > 1*1024*1024:
raise ValidationError(u"Пожалуйста, убедитесь, что размер изображения не больше 1 MiB.")
im = Image.open(StringIO.StringIO(image.read()))
# A dictionary of expected file extensions for each format (as returned by PIL)
expected_file_extensions = {"JPEG": ["jpg", "jpeg"], "PNG": ["png"], "GIF": ["gif"]}
if im.format not in expected_file_extensions:
raise ValidationError(u"Пожалуйста, убедитесь, что изображение имеет один из следующих форматов: JPEG, PNG, GIF.")
if extension not in expected_file_extensions[im.format]:
raise ValidationError(u"Пожалуйста, убедитесь, что формат изображения соответствует его расширению.")
if (im.size[0] < 300 or im.size[1] < 200):
raise ValidationError(u"Пожалуйста, убедитесь, что разрешение фотографии не меньше 300×200.")
if (max(im.size) > 10000):
raise ValidationError(u"Пожалуйста, убедитесь, что разрешение фотографии не больше 10000×10000.")
return image
else:
raise ValidationError(u"При получении изображения возникла ошибка")
class Meta:
model = UserProfile
class RegistrationForm(UserProfileForm):
email = forms.EmailField(max_length=75)
password = forms.CharField(max_length=128)
def clean_email(self):
email = self.cleaned_data['email'].lower()
if User.objects.filter(email=email).exists():
raise forms.ValidationError(u"Пользователь с таким адресом электронной почты уже есть на сайте.")
return email
class Meta:
model = UserProfile
exclude = ('user',)
Соответственно, в бэкэнде авторизации просто позволяем пользователю вводить email с использованием букв любого регистра:
class EmailAuthBackend(ModelBackend):
def authenticate(self, email=None, password=None, **kwargs):
if not email:
return None
try:
user = User.objects.get(email__iexact=email)
except User.DoesNotExist:
return None
except User.MultipleObjectsReturned:
user = User.objects.filter(email__iexact=email)[0]
if user.check_password(password):
return user
К счастью, в Django 1.5 обязательность танцев с бубном заметно уменьшится в связи с появлением определяемых разработчиком моделей User.
0
Sign up to leave a comment.
Django: Генерируем безопасные отчёты об ошибках на сайте