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

时间:2018-07-25 15:13:33

标签: django python-3.x django-models django-signals

我正在尝试按照干草堆文档制作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)

完整错误:

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)

在这里您可以查看文档-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/

如何解决此错误?

1 个答案:

答案 0 :(得分:4)

TL; DR:

您应该替换

getChildAt

使用

def handle_save(self):

问题是,我认为您没有在寻找正确的文档。我想建议this,在它指出的地方

  

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

     

我们稍后再看发件人,但现在看(**kwargs);参数。所有信号都发送关键字参数,并且可以随时更改这些关键字参数。对于**kwargs,它被记录为不发送任何参数,这意味着我们可能会倾向于将信号处理写为request_finished

     

这是错误的-实际上,如果您这样做,Django将抛出错误。那是因为在任何时候都可以将参数添加到信号中,并且您的接收器必须能够处理这些新参数。

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

my_callback(sender)

因此,由于您指定的# Check for **kwargs if not func_accepts_kwargs(receiver): raise ValueError("Signal receivers must accept keyword arguments (**kwargs).") (在这种情况下为recevier)不接受handle_save,因此不可避免地会返回错误。

您的困惑来自以下事实:您要覆盖干草堆的内置handle_save方法。如您在源代码中所看到的,它最初包含**kwargs,但是通过覆盖它。您更改了方法的定义。因此,导致错误。