django-allauth返回错误"Reverse ... with arguments'()'和关键字参数'{}'未找到"

Mar*_*ark 1 python django facebook-login django-allauth

编辑:凯文的答案在下面解决了我的问题.原来"allauth不支持命名空间"所以我不应该把它引入我的urls.py


原始邮寄:

我完全按照教程安装了django-allauth https://github.com/pennersr/django-allauth

我这里有一个非常基本的问题; 甚至在我添加社交集成之前,无法使基本用户登录/退出页面正常工作.

通过导航到/ admin,我点击"退出",所以我不是登录用户.

现在,当我访问时,/accounts/login我遇到了这个错误

NoReverseMatch at /accounts/login/
Reverse for 'account_signup' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
Request Method: GET
Request URL:    http://localhost:5000/accounts/login/
Django Version: 1.6.5
Exception Type: NoReverseMatch
Exception Value:    
Reverse for 'account_signup' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
Run Code Online (Sandbox Code Playgroud)

问题:我是否需要修改默认的allauth views.py来解决这个问题?

在相关的情况下,当我尝试通过shell时,这是同样的问题

(awe01)MoriartyMacBookAir13:getstartapp macuser$ python manage.py shell
Python 2.7.5 (default, Mar  9 2014, 22:15:05) 
>>> from django.core.urlresolvers import reverse
>>> reverse('account_signup')
2014-09-30 16:54:29,256 boto [DEBUG]:Using access key found in config file.
2014-09-30 16:54:29,256 boto [DEBUG]:Using secret key found in config file.
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Users/macuser/Dropbox/code/heroku/awe01/lib/python2.7/site-packages/django/core/urlresolvers.py", line 532, in reverse
    return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
  File "/Users/macuser/Dropbox/code/heroku/awe01/lib/python2.7/site-packages/django/core/urlresolvers.py", line 452, in _reverse_with_prefix
    (lookup_view_s, args, kwargs, len(patterns), patterns))
NoReverseMatch: Reverse for 'account_signup' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
Run Code Online (Sandbox Code Playgroud)

谷歌搜索过去一小时,我看不出我错过了什么.它应该开箱即用,对吧?我看到默认的base.html似乎已经有了这条线,{% load url from future %}

要确认,这里有一些来自我的主要settings.py的摘录(在文件夹shareducate/settings.py中)

"""

"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
import dj_database_url
# from unipath import Path # that's from http://djangosteps.wordpress.com/2013/09/19/setting-up-django-allauth/
BASE_DIR = os.path.dirname(os.path.dirname(__file__))


# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

TEMPLATE_DEBUG = True

ALLOWED_HOSTS = []


TEMPLATE_CONTEXT_PROCESSORS = (
    # from http://django-allauth.readthedocs.org/en/latest/installation.html
    # Required by allauth template tags
    "django.core.context_processors.request",
    # allauth specific context processors
    "allauth.account.context_processors.account",
    "allauth.socialaccount.context_processors.socialaccount",

    # and this due to error message
    "django.contrib.auth.context_processors.auth",
)



AUTHENTICATION_BACKENDS = (
#     http://django-allauth.readthedocs.org/en/latest/installation.html 
    # Needed to login by username in Django admin, regardless of `allauth`
    "django.contrib.auth.backends.ModelBackend",

    # `allauth` specific authentication methods, such as login by e-mail
    "allauth.account.auth_backends.AuthenticationBackend",
)


# Application definition
# auth and allauth settings
LOGIN_REDIRECT_URL = '/'
SOCIALACCOUNT_QUERY_EMAIL = True
SOCIALACCOUNT_PROVIDERS = {
    'facebook': {
#        'AUTH_PARAMS': {'auth_type': 'reauthenticate'},
        'SCOPE': ['email', 'publish_stream'],
        'METHOD': 'js_sdk',  # instead of 'oauth2'
#        'LOCALE_FUNC': 'path.to.callable',
        'VERIFIED_EMAIL': False
    },
#     'google':
#         { 'SCOPE': ['https://www.googleapis.com/auth/userinfo.profile'],
#           'AUTH_PARAMS': { 'access_type': 'online' } },
#     'linkedin':
#       {'SCOPE': ['r_emailaddress'],
#        'PROFILE_FIELDS': ['id',
#                          'first-name',
#                          'last-name',
#                          'email-address',
#                          'picture-url',
#                          'public-profile-url']},
# 
}
# SOCIALACCOUNT_ENABLED = True # @MM completely made that up based on allauth urls.py and https://github.com/flashingpumpkin/django-socialregistration/issues/48

# more settings from allauth
# http://django-allauth.readthedocs.org/en/latest/configuration.html
ACCOUNT_PASSWORD_MIN_LENGTH = 5
# more suggestions from https://speakerdeck.com/tedtieken/signing-up-and-signing-in-users-in-django-with-django-allauth
# ACCOUNT_AUTHENTICATION_METHOD = "username"

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'storages', # http://django-storages.readthedocs.org/en/latest/
    'polls',
    'discover',
    'hello',
    'upload', # from https://github.com/Widen/fine-uploader-server/blob/master/python/django-fine-uploader-s3/settings.py
    'south', # http://south.readthedocs.org/en/latest/tutorial/part1.html
    # The Django sites framework is required
    'django.contrib.sites',

    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    # ... include the providers you want to enable:

    'allauth.socialaccount.providers.facebook',

    'allauth.socialaccount.providers.linkedin',

    'allauth.socialaccount.providers.twitter',

)

SITE_ID = 5 # this corresponds to "127.0.0.1:5000" since I use heroku's foreman start to run things locally
# Not sure about this
# check out https://searchcode.com/codesearch/view/263279/
# I looked at tables. Ran "select * from django_site and it showed that awedify.org was id num 2
# awedify.org # originally just the single character, 1
# that from http://django-allauth.readthedocs.org/en/latest/installation.html

# from http://django-storages.readthedocs.org/en/latest/backends/amazon-S3.html
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
# Note I also specify boto in STATICFILES_STORAGE later down this file





#    Added and removed when trying fineuploader
ADMINS = (
    ('Mark', 'm@domain.com'),
    # ('Your Name', 'your_email@example.com'),
)



MIDDLEWARE_CLASSES = (
    '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',
)

ROOT_URLCONF = 'shareducate.urls'

WSGI_APPLICATION = 'shareducate.wsgi.application'


ALLOWED_HOSTS = ['*']

TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates'),
         'polls/templates/polls',
         'upload/templates/upload',
         # 'polls/templates/polls',
         'messing/templates/messing',
         'discover/templates/discover',
         'allauth/templates/allauth',
        # or see http://djangosteps.wordpress.com/2013/09/19/setting-up-django-allauth/

)

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
#     'django.template.loaders.eggs.Loader',
)


EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' 
# from http://stackoverflow.com/questions/21563227/django-allauth-example-errno-61-connection-refused
Run Code Online (Sandbox Code Playgroud)

我修改了shareducate/urls.py, url(r'^accounts/', include('allauth.urls', namespace='allauth')), 但我没有修改allauth文件夹中的任何内容

注意:通过转到/ admin,我可以以超级用户身份登录.那么肯定的是,访问/ accounts/login会将我重定向到root /,settings.py 如果我注释掉那条线,# LOGIN_REDIRECT_URL = '/'那么肯定会/accounts/profile/按照我的指示http://stackoverflow.com/a/16956071/870121

既然我已经注销了(我通过/ admin界面实现了),allauth程序似乎无法在我访问时处理我 /accounts/login

注意/allauth/templates/account/login.html看起来像这样......我根本没有编辑它

{% extends "account/base.html" %}

{% load i18n %}
{% load account %}
{% load url from future %}

{% block head_title %}{% trans "Sign In" %}{% endblock %}

{% block content %}

<h1>{% trans "Sign In" %}</h1>

{% if socialaccount.providers  %}
<p>{% blocktrans with site.name as site_name %}Please sign in with one
of your existing third party accounts. Or, <a href="{{ signup_url }}">sign up</a>
for a {{site_name}} account and sign in below:{% endblocktrans %}</p>

<div class="socialaccount_ballot">

  <ul class="socialaccount_providers">
    {% include "socialaccount/snippets/provider_list.html" with process="login" %}
  </ul>

  <div class="login-or">{% trans 'or' %}</div>

</div>

{% include "socialaccount/snippets/login_extra.html" %}

{% else %}
<p>{% blocktrans %}If you have not created an account yet, then please
<a href="{{ signup_url }}">sign up</a> first.{% endblocktrans %}</p>
{% endif %}

<form class="login" method="POST" action="{% url 'account_login' %}">
  {% csrf_token %}
  {{ form.as_p }}
  {% if redirect_field_value %}
  <input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
  {% endif %}
  <a class="button secondaryAction" href="{% url 'account_reset_password' %}">{% trans "Forgot Password?" %}</a>
  <button class="primaryAction" type="submit">{% trans "Sign In" %}</button>
</form>

{% endblock %}
Run Code Online (Sandbox Code Playgroud)

猜测

(1)

根据这个答案,http://stackoverflow.com/a/13202435/870121 我想我可能需要修改此allauth/accounts/views.py中的第109行

84 class LoginView(RedirectAuthenticatedUserMixin,
 85                 AjaxCapableProcessFormViewMixin,
 86                 FormView):
 87     form_class = LoginForm
 88     template_name = "account/login.html"
 89     success_url = None
 90     redirect_field_name = "next"
 91 
 92     def get_form_class(self):
 93         return get_form_class(app_settings.FORMS, 'login', self.form_class)
 94 
 95     def form_valid(self, form):
 96         success_url = self.get_success_url()
 97         return form.login(self.request, redirect_url=success_url)
 98 
 99     def get_success_url(self):
100         # Explicitly passed ?next= URL takes precedence
101         ret = (get_next_redirect_url(self.request,
102                                      self.redirect_field_name)
103                or self.success_url)
104         return ret
105 
106     def get_context_data(self, **kwargs):
107         ret = super(LoginView, self).get_context_data(**kwargs)
108         signup_url = passthrough_next_redirect_url(self.request,
109                                                    reverse("account_signup"),
110                                                    self.redirect_field_name)
111         redirect_field_value = self.request.REQUEST \
112             .get(self.redirect_field_name)
113         ret.update({"signup_url": signup_url,
114                     "site": Site.objects.get_current(),
115                     "redirect_field_name": self.redirect_field_name,
116                     "redirect_field_value": redirect_field_value})
117         return ret
118 
119 login = LoginView.as_view()
Run Code Online (Sandbox Code Playgroud)

你看,它reverse("account_signup")没有额外的参数,我没有编辑过这个,因为我认为allauth应该是开箱即用的工具,并且相反通过修补来破坏事物

该行在完整的回溯错误中突出显示.追溯:

File "/Users/macuser/Dropbox/code/heroku/awe01/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  112.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/macuser/Dropbox/code/heroku/awe01/lib/python2.7/site-packages/django/views/generic/base.py" in view
  69.             return self.dispatch(request, *args, **kwargs)
File "/Users/macuser/Dropbox/code/heroku/awe01/getstartapp/allauth/account/views.py" in dispatch
  62.                                             **kwargs)
File "/Users/macuser/Dropbox/code/heroku/awe01/lib/python2.7/site-packages/django/views/generic/base.py" in dispatch
  87.         return handler(request, *args, **kwargs)
File "/Users/macuser/Dropbox/code/heroku/awe01/lib/python2.7/site-packages/django/views/generic/edit.py" in get
  161.         return self.render_to_response(self.get_context_data(form=form))
File "/Users/macuser/Dropbox/code/heroku/awe01/getstartapp/allauth/account/views.py" in get_context_data
  109.                                                    reverse("account_signup"),
File "/Users/macuser/Dropbox/code/heroku/awe01/lib/python2.7/site-packages/django/core/urlresolvers.py" in reverse
  532.     return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
File "/Users/macuser/Dropbox/code/heroku/awe01/lib/python2.7/site-packages/django/core/urlresolvers.py" in _reverse_with_prefix
  452.                              (lookup_view_s, args, kwargs, len(patterns), patterns))
Run Code Online (Sandbox Code Playgroud)

(2)SITE_ID对此非常重要,还是仅仅用于社交整合?

请告知此处可能有意义的故障排除步骤.先谢谢,M

Kev*_*nry 15

让我用一些调试技巧提出这个答案,这些技巧有望在将来证明是有用的.

当你看到特定的Django错误时,它几乎总是意味着你的错误urls.py.这种广泛使用的软件包有一个影响这种基本用法的bug的可能性非常小,因此在这种情况下挖掘源代码可能是浪费了.

你说你安装django-allauth"完全按照教程",但是当我将你的设置与文档进行比较时,我发现了这种差异:

文档: (r'^accounts/', include('allauth.urls'))

您: (r'^accounts/', include('allauth.urls', namespace='allauth'))

因此,使用命名空间似乎有问题.

快速谷歌搜索引发了这个问题,包裹作者解释说不支持命名空间.

因此,如果你摆脱了namespace争论,一切都应该按预期工作.

  • @Mark:很乐意提供帮助,有时只需要一双新鲜的眼睛. (7认同)
  • 我把自己暴露为一个胆小的骗子.非常感谢你在这里结束我的麻烦.是的,我在几小时前修改了这个命名空间参数作为故障排除的一部分而忘记了我已经这样做了.删除它确实解决了我的问题.你已经恢复了我的夜晚和一些自我价值 - 谢谢! (4认同)
  • @KevinChristopherHenry 多么周到且有帮助的回应!我希望所有关于 SO 的答案都是这样的:) (2认同)