ValueError:信号接收器必须接受关键字参数 (**kwargs)。使用 Haystack 时

Pan*_*rma 3 django django-signals django-models python-3.x

我正在尝试按照 haystack 文档制作 SignalProcessor,这是我的代码:

from haystack.signals import RealtimeSignalProcessor
from products.models import ProductCreateModel
from django.db import models
from star_ratings.models import Rating

class BatchingSignalProcessor(RealtimeSignalProcessor):

   def handle_save(self):
        using_backends = self.connection_router.for_write(instance=instance)

        for using in using_backends:
            try:
                index = self.connections[using].get_unified_index().get_index(instance.__class__)
                index.update_object(instance, using=using)
            except NotHandled:
                # TODO: Maybe log it or let the exception bubble?
                pass


    def setup(self):
        models.signals.post_save.connect(self.handle_save, sender=Rating)
Run Code Online (Sandbox Code Playgroud)

完整错误:

Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x00000240811ED400>
Traceback (most recent call last):
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\utils\autoreload.py", line 225, in wrapper
    fn(*args, **kwargs)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\core\management\commands\runserver.py", line 112, in inner_run
    autoreload.raise_last_exception()
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\utils\autoreload.py", line 248, in raise_last_exception
    raise _exception[1]
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\core\management\__init__.py", line 327, in execute
    autoreload.check_errors(django.setup)()
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\utils\autoreload.py", line 225, in wrapper
    fn(*args, **kwargs)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\apps\registry.py", line 120, in populate
    app_config.ready()
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\haystack\apps.py", line 28, in ready
    self.signal_processor = signal_processor_class(connections, connection_router)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\haystack\signals.py", line 20, in __init__
    self.setup()
  File "c:\Users\lenovo\Desktop\My_Django_Stuff\bekaim\search\signals.py", line 21, in setup
    models.signals.post_save.connect(self.handle_save, sender=Rating)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\signals.py", line 28, in connect
    weak=weak, dispatch_uid=dispatch_uid,
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\db\models\signals.py", line 23, in _lazy_method
    return partial_method(sender)
  File "C:\Users\lenovo\AppData\Local\conda\conda\envs\myDjangoEnv\lib\site-packages\django\dispatch\dispatcher.py", line 90, in connect
    raise ValueError("Signal receivers must accept keyword arguments (**kwargs).")
ValueError: Signal receivers must accept keyword arguments (**kwargs)
Run Code Online (Sandbox Code Playgroud)

在这里你可以看到文档 - https://django-haystack.readthedocs.io/en/v2.2.0/signal_processors.html#custom-signalprocessors

这是我在 django 文档中找到但无法找出解决方案的内容 - https://docs.djangoproject.com/en/2.0/_modules/django/dispatch/dispatcher/

如何解决此错误?

sch*_*tte 5

特尔;博士:

你应该更换

def handle_save(self):
Run Code Online (Sandbox Code Playgroud)

def handle_save(self, **kwargs):
Run Code Online (Sandbox Code Playgroud)

问题是,我认为您没有查看正确的文档。我想提出这个建议,它指出

请注意,该函数采用 sender 参数以及通配符关键字参数,(**kwargs);所有信号处理程序都必须采用这些参数。

我们稍后会看看发送者,但现在看看这个**kwargs论点。所有信号都发送关键字参数,并且可以随时更改这些关键字参数。在 的情况下request_finished,它被记录为不发送参数,这意味着我们可能会尝试将我们的信号处理编写为my_callback(sender)

这是错误的——事实上,如果你这样做,Django 会抛出一个错误。这是因为在任何时候参数都可能被添加到信号中,并且您的接收器必须能够处理这些新参数。

基本上,错误处理可以在该connect方法的源代码中看到,

# Check for **kwargs
if not func_accepts_kwargs(receiver):
    raise ValueError("Signal receivers must accept keyword arguments (**kwargs).")
Run Code Online (Sandbox Code Playgroud)

因此,由于您指定的recevierhandle_save在这种情况下)不接受**kwargs它不可避免地返回错误。

您的困惑来自于您正在覆盖handle_savehaystack的内置方法这一事实。正如您在源代码中看到的,它最初包含**kwargs, 但通过覆盖它。您更改了方法的定义。因此,导致错误。