Django 2, python 3.4 no puede decodificar urlsafe_base64_decode (uidb64)

Estoy tratando de activar un usuario por correo electrónico, trabajos por correo electrónico, trabajos de encoding, utilicé un enfoque de django1.11 que estaba funcionando correctamente.

En Django 1.11 lo siguiente se decodifica exitosamente a 28, donde uidb64 = b’Mjg ‘

force_text(urlsafe_base64_decode(uidb64)) 

En django 2 (2, 0, 0, ‘final’, 0) la deencoding del código anterior no funciona y produce un error

 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' () 

También estoy publicando mis opiniones por si acaso.

 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') 

PD: Esto es solo una prueba antes de trabajar con CBV.

edición: incluido el rastreo

 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) 

De acuerdo. Después de una búsqueda de una hora (aún siendo principiante en Python Django), se señaló un cambio relevante en las notas de publicación cuyas definiciones eran poco difíciles para un recién llegado. https://docs.djangoproject.com/en/2.0/releases/2.0/#removed-support-for-bytestrings-in-some-places

Para admitir cadenas nativas de Python 2, las versiones anteriores de Django tenían que aceptar tanto las cadenas de caracteres como las cadenas Unicode. Ahora que se ha eliminado la compatibilidad con Python 2, las circunferencias solo deben encontrarse alrededor de los límites de entrada / salida (manejo de campos binarios o flujos HTTP, por ejemplo). Es posible que tenga que actualizar su código para limitar el uso de la restricción de bytring al mínimo, ya que Django ya no acepta bytestrings en ciertas rutas de código.

Por ejemplo, reverse () ahora usa str () en lugar de force_text () para forzar los argumentos y los kwargs que recibe, antes de colocarlos en la URL. Para las circunferencias, esto crea una cadena con un prefijo b no deseado, así como comillas adicionales (str (b’foo ‘) es “b’foo'”). Para adaptarlo, llame a decode () en el bytestring antes de pasarlo a reverse ().

Totalmente incapaz de trabajar en sus implicaciones, tuve que profundizar en el código del núcleo real de django.

Entonces, desde django 1.11 a 2.0, el cambio de encoding es el siguiente

 'uid': urlsafe_base64_encode(force_bytes(user.pk)), 

a

 'uid': urlsafe_base64_encode(force_bytes(user.pk)).decode(), 

y decodificar desde

 uid = force_text(urlsafe_base64_decode(uidb64)) 

a

  uid = urlsafe_base64_decode(uidb64).decode() 

Eso es. Espero que esto ayude a alguien.