I am trying to upload a file from a form without connection to the database.
Once the form is accepted, I process the file and then delete it. In web2py it works perfectly for me with SQLFORM.factory.
The code that I use in py4web and that gives an error is the following:
form = Form(
table=[
Field(
'c_file', 'upload', label='Upload File',
uploadfolder=uploadfolder,
requires=IS_UPLOAD_FILENAME(extension='(htm|html)'),
)
],
formstyle=FormStyleBulma,
submit_value='Process file',
)
if form.accepted:
etc...
The error trace is as follows
Traceback (most recent call last):
File "/home/carlos/programming/app1/cc-v3/venv38/lib/python3.8/site-packages/py4web/core.py", line 932, in wrapper
ret = func(*func_args, **func_kwargs)
File "/home/carlos/programming/app1/cc-v3/venv38/lib/python3.8/site-packages/py4web/core.py", line 917, in wrapper
raise context["exception"]
File "/home/carlos/programming/app1/cc-v3/venv38/lib/python3.8/site-packages/py4web/core.py", line 896, in wrapper
context["output"] = func(*args, **kwargs)
File "/home/carlos/programming/app1/cc-v3/apps/mcc/controllers/first_pedidos.py", line 294, in import_order
form = Form(
File "/home/carlos/programming/app1/cc-v3/venv38/lib/python3.8/site-packages/py4web/utils/form.py", line 827, in __init__
value = field.store(
File "/home/carlos/programming/app1/cc-v3/venv38/lib/python3.8/site-packages/pydal/objects.py", line 2108, in store
uuid_key = self._db.uuid().replace("-", "")[-16:]
AttributeError: 'NoneType' object has no attribute 'uuid'
After a bit of debugging I see that self._db is None.
Reviewing the pydal and SQLFORM.factory code a bit, I already see what the problem is with the py4web form.
SQLFORM.factory uses a dummy_db so everything works fine.
The solution that works for me is the following.
file form.py line 720:
```
if isinstance(table, list):
dbio = False
# Mimic a table from a list of fields without calling define_table
form_name = form_name or "no_table"
dummy_db = DAL(None)
dummy_table = dummy_db.define_table(form_name)
for field in table:
field.bind(dummy_table)
# field.tablename = getattr(field, "tablename", form_name)
´´´
@Massimo what do you think, can it be an acceptable solution?
Carlos.
--
You received this message because you are subscribed to the Google Groups "py4web" group.
To unsubscribe from this group and stop receiving emails from it, send an email to py4web+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/py4web/82307677-18fd-4dc8-a49f-28e37dcafcacn%40googlegroups.com.
I had focused only on modifying the form.py file, I did not want to touch pydal
Continuing with the solution you are providing, I see that it is not enough.
On line 2108 of the pydal/objects.py file
change
uuid_key = self._db.uuid().replace(“-“, “”)[-16:]
by
uuid_key = uuidstr().replace(“-“, “”)[-16:]
It works well.
But just below we have
encoded_filename = to_native(base64.urlsafe_b64encode(to_bytes(filename)))
newfilename = "%s.%s.%s.%s" % (
self._tablename,
self.name,
uuid_key,
encoded_filename,
)
we have an error as self._tablename has no value
To solve the problem we can modify form.py like this
if isinstance(table, list):
dbio = False
# Mimic a table from a list of fields without calling define_table
form_name = form_name or "no_table"
for field in table:
field.tablename = field._tablename = getattr(field, "tablename", form_name)
Or make more changes to pydal/objects.py