Closed PCatinean closed 5 years ago
Hello @PCatinean . When I print the source traceback, I get this:
Traceback (most recent call last):
File "/usr/local/lib/python3.5/xmlrpc/client.py", line 509, in __dump
f = self.dispatch[type(value)]
KeyError: <class 'collections.defaultdict'>
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/odoo/custom/src/odoo/odoo/service/wsgi_server.py", line 125, in wsgi_xmlrpc
response = xmlrpclib.dumps((result,), methodresponse=1, allow_none=False)
File "/usr/local/lib/python3.5/xmlrpc/client.py", line 951, in dumps
data = m.dumps(params)
File "/usr/local/lib/python3.5/xmlrpc/client.py", line 501, in dumps
dump(v, write)
File "/usr/local/lib/python3.5/xmlrpc/client.py", line 523, in __dump
f(self, value, write)
File "/usr/local/lib/python3.5/xmlrpc/client.py", line 614, in dump_instance
self.dump_struct(value.__dict__, write)
File "/usr/local/lib/python3.5/xmlrpc/client.py", line 594, in dump_struct
dump(v, write)
File "/usr/local/lib/python3.5/xmlrpc/client.py", line 523, in __dump
f(self, value, write)
File "/usr/local/lib/python3.5/xmlrpc/client.py", line 614, in dump_instance
self.dump_struct(value.__dict__, write)
File "/usr/local/lib/python3.5/xmlrpc/client.py", line 594, in dump_struct
dump(v, write)
File "/usr/local/lib/python3.5/xmlrpc/client.py", line 513, in __dump
raise TypeError("cannot marshal %s objects" % type(value))
TypeError: cannot marshal <class 'collections.defaultdict'> objects
It complains about the RPC method returning a collections.defaultdict
. The issue is because XMLRPC (and JSONRPC too, I guess) cannot transfer this type of objects.
The issue is probably in you custom module (I don't use defaultdict
internally in Odooly). You have to cast the result (or its subelement) to a dict(...)
when you return it.
Ah so basically when a method returns a record/recordset the lib does not parse it. I assume it would get the id from the returned value and browse it so generate a local representation of the object.
I assume I would need to make a duplicate method or add an argument to change the return type from record/recordset to dictionary then?
Actually it's documented on odoo website: "methods expressed purely in the new API are not available over RPC" https://www.odoo.com/documentation/master/reference/orm.html#compatibility-between-new-api-and-old-api
So you need to decorate the method with @api.multi
or @api.model
if you want to expose it to RPC.
I'm reading more about it.
Actually if your method returns a Recordset, and you want to use it with RPC, you need to decorate it twice : @api.multi or @api.model
and @api.returns('self')
.
@api.multi
@api.returns('self')
def refund(self, date_invoice=None, date=None, description=None, journal_id=None):
new_invoices = self.browse()
for invoice in self:
# create the new invoice
values = self._prepare_refund(invoice, ...)
refund_invoice = self.create(values)
message = _("...")
refund_invoice.message_post(body=message)
new_invoices += refund_invoice
return new_invoices
Indeed, as always right you are @florentx. In order to process these values via RPC the returns decorator is needed.
Didn't pay much attention to it before but now I certainly will. Thanks a lot for giving a helping hand on this, I appreciate it tremendously.
I hope this is not an error from my side but I installed odooly in a python virtualenvironment (version 2.7) using pip.
I have a remote method that when executed it creates a project and returns the recordset.
This is what odooly throws when that value is sent:
Many thanks for opensourcing this great lib, best way to execute remote rpc for Odoo by far.