sqladmin icon indicating copy to clipboard operation
sqladmin copied to clipboard

Overriden form text field with FileUpload field.

Open smbrine opened this issue 11 months ago • 7 comments

Checklist

  • [X] The bug is reproducible against the latest release or master.
  • [X] There are no similar issues or pull requests to fix it yet.

Describe the bug

Since I already have a solution but I don't know whether it's useful or not, I will be short. I have a simple logic in my app. User can upload a .json file, async def on_model_change(self, data, model, is_created, request): will open it, load json and pass it further as a dict to save it to postgres' JSONB field. The problem is that the SQLAdmin itself still considers it being of type UploadFile and hence line 689 in application.py was raising an AttributeError: 'dict' object has no attribute 'name'. My solution is to basically just pass f's value as is since there's no case when f can have name or read attribute in this elif.

Steps to reproduce the bug

No response

Expected behavior

No response

Actual behavior

No response

Debugging material

os, python, sqladmin version

Environment

  • OS: macOS Sonoma 14.2.1
  • Python: 3.11.3
  • SQLAdmin: 0.16.1

Additional context

No response

smbrine avatar Mar 04 '24 20:03 smbrine

I think I understand what the issue is, but this was specifically added to make sqladmin work with fastapi-storages. But I assume you are not using fastapi-storages but just using a FileUpload field, right?

aminalaee avatar Mar 05 '24 12:03 aminalaee

Yeah, I use JSONB field in SQLAlchemy, override it with FileUpload field in the admin form, parse json from the file in the on_model_updateand pass the resulting data forward. According to my tests, there's no such case except for mine to get into the elif statement I changed. It also passes all the tests hence it's definitely not a destructive change!

smbrine avatar Mar 06 '24 12:03 smbrine

Yeah that makes sense. I will add a minor change to your PR as I think the current code was because of a hacky workaround I did for fastapi-storages.

aminalaee avatar Mar 06 '24 16:03 aminalaee

@smbrine I think I was a bit confused and my previous comment was not accurate. The issue is that when uploading the file everything works es you explained, you open the file and pass the content as dict to be saved in DB. The issue comes up when you want to edit the inserted object. You are storing the file content in JSONB but in the edit form you want to show FileField with WTForms. SQLAdmin expects that since this is a FileField, previously a file was stored for this. Maybe a good question is why don'y you specify a TextField and validate the JSON with the hooks? Since you aren't really storing/editing the file.

aminalaee avatar Mar 07 '24 13:03 aminalaee

Because in that case there will be no way to submit a file (except for fully custom form but it's definitely not what I want since it takes way more time to do).

smbrine avatar Mar 07 '24 18:03 smbrine

But is this accomplished in any tool like Django admin and flask-admin without modifying the behaviour completely? The reason I ask is that is that this is a very specific use-case that you want the create form to accept a file, but in the edit form you want to edit a JSON field.

aminalaee avatar Mar 07 '24 20:03 aminalaee

Seems like I have incorrectly explained my point. It's not that I want to have a JSON field in the edit form, there is also UploadForm since I don't want users to deal with TextAreas. The idea is for example if one wants to store, say, parseable text file in db in a parsed way (just like my case when I store .json file as JSONB instead of the file itself). I haven't used flask-admin, nor do I have expertise in Django admin hence I can't judge here. My point is that I have handled my specific scenario without affecting any other scenarios and now it's fully up to you but there's always a chance that there will be someone else who will also decide to override a field with a FileUpload!

smbrine avatar Mar 08 '24 21:03 smbrine