Cuando un usuario hace clic en 'iniciar sesión', quiero que inicien sesión y se redirijan a, es decir, www.exampledomain.com/accounts/usernameGoesHere/

Aquí están mis URL de nivel superior:

from django.conf.urls import url, include
from django.contrib import admin

# Namespace URLs
app_name = "pto_request"

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^accounts/', include('accounts.urls')),
]

Y aquí están las URL para cuentas:

from django.conf.urls import url
from django.contrib.auth.decorators import login_required
from accounts.views import (login_view, register_view, logout_view)
from . import views

app_name = 'accounts'

urlpatterns = [
    # root url will look like www.website.com/accounts/

    url(r'^login/$', login_view, name='login'),
    url(r'^logout/$', logout_view, name='logout'),
    url(r'^register/$', register_view, name='register'),
    url(r'^(?P<username>[0-9a-zA-Z._]+)/$', login_required(views.IndexView.as_view()), name = 'index'),
]

Esta es mi vista de inicio de sesión:

def login_view(request):
    title = "Login"
    user_form = UserLoginForm(request.POST or None)
    if user_form.is_valid():
        username = user_form.cleaned_data.get('username')
        password = user_form.cleaned_data.get('password')
        user = authenticate(username=username, password=password)
        login(request, user)
        return redirect(reverse('accounts:index', args=[username]))
    return render(request, 'form.html', {'user_form':user_form, 'title':title})

Y finalmente este es el registro de rastreo del error que estoy recibiendo:

Environment:


Request Method: GET
Request URL: http://localhost:8000/accounts/FlashBanistan/

Django Version: 1.10.5
Python Version: 3.5.2
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'crispy_forms',
 'datetimewidget',
 'accounts']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.locale.LocaleMiddleware']


Template error:
In template C:\django projects\PTO\accounts\templates\accounts\index.html, error at line 0
   Reverse for 'index' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) tried: ['accounts/(?P<username>[0-9a-zA-Z._]+)/$']   1 : {% extends 'base.html' %}
   2 : {% load crispy_forms_tags %}
   3 : 
   4 : {% block content %}
   5 : 
   6 : {{ form.media }}
   7 : 
   8 : 
   9 : <div class="container">
   10 :   <div id="calendar">


Traceback:

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\exception.py" in inner
  39.             response = get_response(request)

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  217.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  215.                 response = response.render()

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\response.py" in render
  109.             self.content = self.rendered_content

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\response.py" in rendered_content
  86.         content = template.render(context, self._request)

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\backends\django.py" in render
  66.             return self.template.render(context)

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py" in render
  208.                     return self._render(context)

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py" in _render
  199.         return self.nodelist.render(context)

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py" in render
  994.                 bit = node.render_annotated(context)

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py" in render_annotated
  961.             return self.render(context)

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\loader_tags.py" in render
  174.         return compiled_parent._render(context)

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py" in _render
  199.         return self.nodelist.render(context)

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py" in render
  994.                 bit = node.render_annotated(context)

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py" in render_annotated
  961.             return self.render(context)

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\defaulttags.py" in render
  315.                 return nodelist.render(context)

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py" in render
  994.                 bit = node.render_annotated(context)

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\base.py" in render_annotated
  961.             return self.render(context)

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\template\defaulttags.py" in render
  439.             url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\urls\base.py" in reverse
  91.     return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))

File "C:\Users\achesley\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\urls\resolvers.py" in _reverse_with_prefix
  392.             (lookup_view_s, args, kwargs, len(patterns), patterns)

Exception Type: NoReverseMatch at /accounts/FlashBanistan/
Exception Value: Reverse for 'index' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) tried: ['accounts/(?P<username>[0-9a-zA-Z._]+)/$']
0
FlashBanistan 13 ene. 2017 a las 02:44

3 respuestas

La mejor respuesta

Paso 1. Mueve tu URL index a la última y dale un patrón para aceptar solo nombre de usuario. Mover la URL index a la última es importante, o anulará todas las otras URL en el mismo archivo de URL, por ejemplo, login, logout.

app_name = 'accounts'

urlpatterns = patterns(
    '',
    url(r'^login/', login_view, name='login'),
    url(r'^logout/', logout_view, name='logout'),
    url(r'^register/', register_view, name='register'),
    #
    # +------------ this url should come at last !!!!
    # |
    # v
    url(r'^(?P<username>[0-9a-zA-Z._]+)/$', login_required(views.IndexView.as_view()), name = 'index'), name = 'index'),
)

Paso 2. redirect a tu URL index con el nombre de usuario registrado.

return redirect(reverse('accounts:index', args=(username, )))

EDITAR 2 Error de plantilla de fijación

Según su seguimiento de la pila, el error ocurrió en su plantilla, y django no puede revertir una url para index. Después de verificar su código en su plantilla, descubrí que ha llamado a una función url con accounts:index como parámetro, pero sin especificar el nombre de usuario kwarg en su llamada al método.

Para que pueda corregir el error con el siguiente código:

{% if user %}
<li><a href="{% url 'accounts:index' user.username %}"><span class="glyphicon glyphicon-user"></span> {{ user.username }}</a></li>
{% endif %}
1
Enix 15 ene. 2017 a las 08:49

El patrón de aceptación de URL de Django, eso significa que puede configurar una URL para la página de inicio como:

url(r'^(?P<username>[a-zA-Z]*)$', views.userhome, name = 'index'),

En la vista de índice de su usuario, obtendrá una variable de url, por lo que la función (igual para la vista basada en clase) le gustará:

def userhome(request, username):

Para usar esta url, puede usar la función reverse:

#after login...
return redirect(revers('index', args=[username]))

Y aquí hay algunos consejos útiles para usted:

  1. Mejor escriba su decorador en su views.py, ya que escribir en su urls.py lo hará demasiado desordenado.
  2. Intente utilizar la función inversa para obtener una URL en lugar de escribir su código directamente

Para obtener más información sobre la configuración inversa y url, puede consultar documento de Django.

0
Community 23 may. 2017 a las 12:17

Otra forma es agregar el nombre de usuario como una cadena de consulta en su función de redireccionamiento. De esta manera no tiene que cambiar sus URL:

return redirect("/accounts/?username=%s" % user.username)

Además, puede obtener el usuario de request.user en la vista (sin tener que agregarlo a la url), que es lo que recomendaría, aparte de si por motivos estéticos lo desea en la url.

Aquí hay otra función de inicio de sesión para referencia que corrige algunos de los problemas discutidos en los comentarios de su pregunta:

def login(request):

    username = request.POST.get('username')
    password = request.POST.get('password')
    if username and password:

        # Make sure its an active user, or else return an error message.
        user = authenticate(username=username, password=password)
        if user is not None and user.is_active:
            auth_login(request, user)
            next = request.session.get('next', 'root')
            return redirect(next)
        else:
            messages.warning(request, "Invalid username / password.")

    return render(request, 'login.html')
0
David542 13 ene. 2017 a las 01:05