i am trying to activate a user by email, email works, encoding works, i used an approach from django1.11 which was working successfully.
我试图通过电子邮件,电子邮件工作,编码工作激活用户,我使用django1.11的方法,该方法成功运行。
In Django 1.11 the following decodes successfully to 28, where uidb64 = b'Mjg'
在Django 1.11中,以下解码成功到28,其中uidb64 = b'Mjg'
force_text(urlsafe_base64_decode(uidb64))
In django 2 (2, 0, 0, 'final', 0) the above code decode does not work and results in an error
在django 2(2,0,0,'final',0)中,上述代码解码不起作用并导致错误
django.utils.encoding.DjangoUnicodeDecodeError: 'utf-8' codec can't decode byte 0xc8 in position 1: invalid continuation byte. You passed in b'l\xc8\xe0' (<class 'bytes'>)
I am also posting my views just in case
我也发布了我的观点以防万一
from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False
user.save()
# auth_login(request, user)
message = render_to_string('user_activate_email.html', {
'user': user,
'domain': Site.objects.get_current().domain,
'uidb64': urlsafe_base64_encode(force_bytes(user.pk)),
'token': account_activation_token.make_token(user),
})
mail_subject = 'Activate your blog account.'
to_email = form.cleaned_data.get('email')
email = EmailMessage(mail_subject, message, to=[to_email])
email.send()
messages.info(
request, 'Activation link has been sent to your email!')
# return redirect('home')
return render(request, 'index.html')
else:
form = SignUpForm()
return render(request, 'user_action.html', {'form': form})
def activate(request, uidb64, token):
try:
import pdb;
pdb.set_trace()
uid = urlsafe_base64_decode(uidb64).decode()
user = User.objects.get(pk=uid)
except(TypeError, ValueError, OverflowError):
user = None
if user is not None and account_activation_token.check_token(user, token):
user.refresh_from_db()
user.is_active = True
user.save()
auth_login(request, user)
messages.info(request, 'Your account has been activated successfully!')
return redirect('events:home')
else:
messages.info(
request, 'Activation link is invalid or has been activated')
return redirect('events:home')
PS: This is just a trial before i work with CBV.
PS:这只是我与CBV合作之前的试验。
edit: including traceback
编辑:包括追溯
System check identified no issues (0 silenced).
December 15, 2017 - 05:51:01
Django version 2.0, using settings 'event_management.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
> /home/vipinmohan/django2-0/event/event_management/users/views.py(88)activate()
-> uid = urlsafe_base64_decode(uidb64).decode()
(Pdb) n
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcc in position 1: invalid continuation byte
> /home/vipinmohan/django2-0/event/event_management/users/views.py(88)activate()
-> uid = urlsafe_base64_decode(uidb64).decode()
(Pdb) n
> /home/vipinmohan/django2-0/event/event_management/users/views.py(90)activate()
-> except(TypeError, ValueError, OverflowError):
(Pdb) n
> /home/vipinmohan/django2-0/event/event_management/users/views.py(91)activate()
-> user = None
(Pdb)
1 个解决方案
#1
17
Ok. after hour long search (still beginner at python django), a relevant change was pointed in release notes whose definitions were little difficult for a newcomer. https://docs.djangoproject.com/en/2.0/releases/2.0/#removed-support-for-bytestrings-in-some-places
好。经过一小时的搜索(仍然是python django的初学者),在发行说明中指出了一个相关的变化,其定义对于新手来说并不困难。 https://docs.djangoproject.com/en/2.0/releases/2.0/#removed-support-for-bytestrings-in-some-places
To support native Python 2 strings, older Django versions had to accept both bytestrings and unicode strings. Now that Python 2 support is dropped, bytestrings should only be encountered around input/output boundaries (handling of binary fields or HTTP streams, for example). You might have to update your code to limit bytestring usage to a minimum, as Django no longer accepts bytestrings in certain code paths.
为了支持本机Python 2字符串,旧的Django版本必须接受字节串和unicode字符串。现在删除了Python 2支持,只应在输入/输出边界(例如处理二进制字段或HTTP流)周围遇到字节串。您可能必须更新代码以将字节串使用限制到最小,因为Django不再接受某些代码路径中的字节串。
For example, reverse() now uses str() instead of force_text() to coerce the args and kwargs it receives, prior to their placement in the URL. For bytestrings, this creates a string with an undesired b prefix as well as additional quotes (str(b'foo') is "b'foo'"). To adapt, call decode() on the bytestring before passing it to reverse().
例如,reverse()现在使用str()而不是force_text()强制它接收到的args和kwargs,然后放入URL。对于字节串,这会创建一个带有不需要的b前缀的字符串以及其他引号(str(b'foo')是“b'foo”“)。要进行调整,在将字节串传递给reverse()之前调用bytestring()。
Totally unable to work on its implications, i had to go deeper into the actual django core code.
完全无法解决其影响,我不得不深入研究实际的django核心代码。
So from django 1.11 to 2.0 the encode change is as follows
所以从django 1.11到2.0编码的变化如下
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
to
至
'uid': urlsafe_base64_encode(force_bytes(user.pk)).decode(),
and decode from
和解码
uid = force_text(urlsafe_base64_decode(uidb64))
to
至
uid = urlsafe_base64_decode(uidb64).decode()
Thats it. Hope this helps someone.
而已。希望这有助于某人。
#1
17
Ok. after hour long search (still beginner at python django), a relevant change was pointed in release notes whose definitions were little difficult for a newcomer. https://docs.djangoproject.com/en/2.0/releases/2.0/#removed-support-for-bytestrings-in-some-places
好。经过一小时的搜索(仍然是python django的初学者),在发行说明中指出了一个相关的变化,其定义对于新手来说并不困难。 https://docs.djangoproject.com/en/2.0/releases/2.0/#removed-support-for-bytestrings-in-some-places
To support native Python 2 strings, older Django versions had to accept both bytestrings and unicode strings. Now that Python 2 support is dropped, bytestrings should only be encountered around input/output boundaries (handling of binary fields or HTTP streams, for example). You might have to update your code to limit bytestring usage to a minimum, as Django no longer accepts bytestrings in certain code paths.
为了支持本机Python 2字符串,旧的Django版本必须接受字节串和unicode字符串。现在删除了Python 2支持,只应在输入/输出边界(例如处理二进制字段或HTTP流)周围遇到字节串。您可能必须更新代码以将字节串使用限制到最小,因为Django不再接受某些代码路径中的字节串。
For example, reverse() now uses str() instead of force_text() to coerce the args and kwargs it receives, prior to their placement in the URL. For bytestrings, this creates a string with an undesired b prefix as well as additional quotes (str(b'foo') is "b'foo'"). To adapt, call decode() on the bytestring before passing it to reverse().
例如,reverse()现在使用str()而不是force_text()强制它接收到的args和kwargs,然后放入URL。对于字节串,这会创建一个带有不需要的b前缀的字符串以及其他引号(str(b'foo')是“b'foo”“)。要进行调整,在将字节串传递给reverse()之前调用bytestring()。
Totally unable to work on its implications, i had to go deeper into the actual django core code.
完全无法解决其影响,我不得不深入研究实际的django核心代码。
So from django 1.11 to 2.0 the encode change is as follows
所以从django 1.11到2.0编码的变化如下
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
to
至
'uid': urlsafe_base64_encode(force_bytes(user.pk)).decode(),
and decode from
和解码
uid = force_text(urlsafe_base64_decode(uidb64))
to
至
uid = urlsafe_base64_decode(uidb64).decode()
Thats it. Hope this helps someone.
而已。希望这有助于某人。