类型错误:__init __()收到了一个意外的关键字参数'providing_args'。

13
我正在创建一个Django网站,并最近使用allauth包添加了权限/搜索功能。当我尝试通过docker运行网站时,我收到以下错误消息: “/usr/local/lib/python3.9/site-packages/allauth/account/signals.py”路径下的第5行代码"user_logged_in = Signal(providing_args=["request", "user"])" 报错 "TypeError: init() got an unexpected keyword argument 'providing_args'”。
造成这个错误的原因是什么?通常类型错误是由于不正确的models.py文件引起的,但由于它是外部包的一部分,所以我无法访问该文件。
Urls.py
urlpatterns = [
    path('admin/', admin.site.urls),

    path('accounts/', include('allauth.urls')),

    path('accounts/', include('accounts.urls')),
    
    path('', include('climate.urls')),
    
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

if settings.DEBUG:
    import debug_toolbar
    urlpatterns = [
        path('__debug__/', include(debug_toolbar.urls)),
    ] + urlpatterns

Models.py

class Country(models.Model):
    id = models.UUIDField(
        primary_key= True,
        db_index = True,
        default=uuid.uuid4,
        editable= False
    )
    name = models.CharField(max_length=50)
    population = models.IntegerField(default=1)
    emissions = models.FloatField(default=1)
    reason = models.CharField(default="", max_length=100)
    flags = models.ImageField(upload_to='images/', default="")
    page = models.URLField(max_length=300, default="")

    def save(self, *args, **kwargs):
        super(Country, self).save(*args, **kwargs)

    class Meta:
        verbose_name_plural = 'countries'
        indexes = [
            models.Index(fields=['id'], name='id_index')
        ]
        permissions = {
            ("special_status", "Can read all countries")
        }

    def __str__(self):
        return self.name

    def flag(self):
        return u'<img src="%s" />' % (self.flags.url)

    def get_absolute_url(self):
        return reverse('country_detail', args =[str(self.id)])

    flag.short_description = 'Flag'

我的settings.py处理allauth相关内容。

AUTH_USER_MODEL = 'accounts.CustomUser'
LOGIN_REDIRECT_URL = 'climate:home'
ACCOUNT_LOGOUT_REDIRECT = 'climate:home'
ACCOUNT_SESSION_REMEMBER = True
ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE = False
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_UNIQUE_EMAIL = True

完整的回溯信息:

Traceback (most recent call last):

  File "/usr/local/lib/python3.9/threading.py", line 954, in _bootstrap_inner

    self.run()

  File "/usr/local/lib/python3.9/threading.py", line 892, in run

    self._target(*self._args, **self._kwargs)

  File "/usr/local/lib/python3.9/site-packages/django/utils/autoreload.py", line 64, in wrapper

    fn(*args, **kwargs)

  File "/usr/local/lib/python3.9/site-packages/django/core/management/commands/runserver.py", line 115, in inner_run

    autoreload.raise_last_exception()

  File "/usr/local/lib/python3.9/site-packages/django/utils/autoreload.py", line 87, in raise_last_exception

    raise _exception[1]

  File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 381, in execute

    autoreload.check_errors(django.setup)()

  File "/usr/local/lib/python3.9/site-packages/django/utils/autoreload.py", line 64, in wrapper

    fn(*args, **kwargs)

  File "/usr/local/lib/python3.9/site-packages/django/__init__.py", line 24, in setup

    apps.populate(settings.INSTALLED_APPS)

  File "/usr/local/lib/python3.9/site-packages/django/apps/registry.py", line 114, in populate

    app_config.import_models()

  File "/usr/local/lib/python3.9/site-packages/django/apps/config.py", line 300, in import_models

    self.models_module = import_module(models_module_name)

  File "/usr/local/lib/python3.9/importlib/__init__.py", line 127, in import_module

    return _bootstrap._gcd_import(name[level:], package, level)

  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import

  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load

  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked

  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked

  File "<frozen importlib._bootstrap_external>", line 790, in exec_module

  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed

  File "/usr/local/lib/python3.9/site-packages/allauth/account/models.py", line 12, in <module>

    from . import app_settings, signals

  File "/usr/local/lib/python3.9/site-packages/allauth/account/signals.py", line 5, in <module>

    user_logged_in = Signal(providing_args=["request", "user"])

TypeError: __init__() got an unexpected keyword argument 'providing_args'

错误的完整回溯是什么? - Carcigenicate
刚刚将其添加到问题中。 - huntere2501
1
你使用的Django和allauth版本是什么?刚刚查看了各种文档和源代码的不同版本,似乎在Django 3.1中提供providing_args是有效的,但在3.2中无效,而allauth v0.46.0声称提供Django 3.2兼容性。所以我猜你正在使用Django 3.2(或更高版本),但是allauth的版本是0.46.0之前的版本? - Robin Zigmond
我确实正在使用Django 4.0和allauth 0.42.0,那么我需要降级Django还是更新allauth? - huntere2501
抱歉,我错过了你的回复(标记我的话会帮助我及时知道!)。是的,你需要做其中之一 - 甚至可能两者都要做(我不确定最新的allauth是否支持Django 4)。 - Robin Zigmond
8个回答

18

根据评论,您正在使用Django 4.0和旧版的AllAuth。所以您只需要更新AllAuth就可以解决问题。


然而,其他已经升级了AllAuth并且正在运行Django 4.0的人,但仍然看到此错误的可能有自定义的AllAuth或其他信号注册,包括`providing_args`参数。
在这种情况下,您需要搜索项目中的任何信号(例如AllAuth中经常被覆盖的信号:`user_logged_in`或`email_changed`),并从`Signal`圆括号中删除`providing_args = ['request', 'user', 'signup']`或其他变量。
有关更多信息以及显示如何将每个`providing_args`参数移动到注释行的示例差异,请参见下文。
在Django 3.1中,废弃了使用providing_args参数的功能。可以在3.1版本发布说明的Misc section中找到相关信息。
这一功能被移除是因为该参数除了作为文档外没有其他作用。如果这听起来很奇怪,那是因为它确实很奇怪。参数应该指示传递的数据。这可能就是为什么将其弃用的原因。
在Django 4.0中,这个参数被彻底删除了,任何调用带有providing_args参数的Signal()函数的代码都会触发TypeError错误,就像你遇到的那样: TypeError: Signal.__init__() got an unexpected keyword argument 'providing_args' AllAuth在2020年9月删除了对此参数的使用。 (请参阅original reportreferenced diff上此问题的报告)
在本质问答串中提问的人运行的AllAuth版本是0.42.0,其中不包括这个更改,因此与Django 4.0不兼容。
截至今天,最后一个与Django 3.2.9兼容的版本是Django AllAuth 0.42.0

7

我通过替换来解决了相同的问题

check_request_enabled = Signal(providing_args=["request"])

to

check_request_enabled = Signal("request")

现在它完美地工作了。


如果您想在 https://dj-rest-auth.readthedocs.io/en/latest/demo.html 上测试演示,则此方法可行。 - Khaled Adrani

3
这是为那些在使用Django 4.0且没有使用AllAuth的人解决问题的。我遇到了相似的问题。然而,我没有使用AllAuth。问题是Django 4.0没有任何提供"providing_args"参数,所以信号是这样声明的。
from django.dispatch import Signal

model_delete_signal = Signal()

现在,你可以在发送信号时发送任何参数,这些参数将在接收器中的kwargs中接收到。

例如,在我的自定义删除函数中发送信号时,我发送了以下instance参数。

model_delete_signal.send(sender='session_delete', instance=self)

并通过接收器在内部以这种方式接收它

@receiver(session_delete)
def delete_session(sender, **kwargs):
    instance = kwargs['instance']

请注意,对于任何没有providing_args参数的Singal()函数的Django版本,解决方案都是相同的。

1
在 Django 4 的新版本中,您可以直接使用没有参数的 Signal。示例如下:
from django.dispatch import Signal, receiver
notification=Signal()
@receiver(notification)
def show_notification(sender, **kwargs):
    print("sender,", sender)
    print("Kwargs", kwargs)
    print("Notification")        

并且在使用这个信号之后,写成这样。
notification.send(sender=None, request=request, user=['Sakib', 'Malik'])

1

有更好的解释,但这是对我有用的...

根据Django

Signal的纯文档提供参数“providing_args”已被弃用。如果您依赖此参数作为文档,请将文本移动到代码注释或docstring中。

只需在本地项目存储中的signals.py文件中注释掉以下代码:

user_logged_in = Signal(providing_args=["request", "user"])

# Typically followed by `user_logged_in` (unless, e-mail verification kicks in)
user_signed_up = Signal(providing_args=["request", "user"])

password_set = Signal(providing_args=["request", "user"])
password_changed = Signal(providing_args=["request", "user"])
password_reset = Signal(providing_args=["request", "user"])

email_confirmed = Signal(providing_args=["request", "email_address"])
email_confirmation_sent = Signal(
    providing_args=["request", "confirmation", "signup"])

email_changed = Signal(
    providing_args=[
        "request", "user",
        "from_email_address", "to_email_address"])
email_added = Signal(providing_args=["request", "user", "email_address"])
email_removed = Signal(providing_args=["request", "user", "email_address"])

你可以在/usr/local/lib/python3.10/site-packages/allauth/account/signals.py中找到它。

1

我不知道为什么会发生这种情况,但是(在我的电脑上工作),我通过替换解决了同样的问题。

user_logged_in = Signal(providing_args=["request", "user"])

使用

user_logged_in = Signal()

在 /usr/local/lib/python3.9/site-packages/allauth/account/signals.py 中


1
请查看我的答案,了解为什么这个方法可行。 - Rob
1
非常感谢,你真的做得很好地解释了它。 - Oussama Tachi

0

来自Django 3.1文档

Signal的纯文档提供参数(providing_args)已被弃用。如果您依赖此参数作为文档,请将文本移动到代码注释或docstring中。


0
首先检查你的 `signals.py` 文件,在那里你使用了 `Signal()` 函数。
SignalName = Signal(providing_args=["request", "user"])

Signal()函数中,不要将providing_args作为参数提供,而是像这样提供参数。
SignalName = Signal(["request", "user"])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接