iommirocks / iommi

Your first pick for a django power cord
http://iommi.rocks
BSD 3-Clause "New" or "Revised" License
718 stars 47 forks source link

Link + delete for FileField / ImageField in edit forms #428

Open berycz opened 1 year ago

berycz commented 1 year ago

I think FileField should have a template like ImageField has image_row.html with a link to the field.value.url

plus both should have a way to "delete" the file, probably a checkbox name="{field.name}__remove" and on save if checked iommi should clear the value - I guess in file_write_to_instance...?

an endpoint called via ajax is not a good idea imo, it would clear the value before saving via subbmit button, that can have consequences, e.g. I use a "last_modification" field to prevent write-read conflict

I would also recommend settings via extra: field.extra__preview_template for the link/img tag field.extra__delete_button_name default f"{field.name}__remove" (double underscore should be safe?) field.extra__delete_button_template e.g. for removing the checkbox (someone may want a custom solution) ?field.extra__on_delete - might be useful for removing the file from storage, but I'm not sure about this one, because it is also solvable via model diff mixin

berycz commented 1 year ago

one more thing I was thinking about in image_row.html you have <img src="{{ field.value.url }}">, what if it's a form without auto__model, can't you pass a simple file object via initial? Or actually what are you supposed to pass? that might be good to put in the docs

berycz commented 1 year ago

I'm thinking now that it might actually be better to make it a Field.preview for file and image, e.g. something like

class FilePreview(Fragment):  # not sure about the name
    preview: Fragment = Refinable()  # not sure about the name
    delete: Fragment = Refinable()  #  = Field.boolean(...), no idea where to define it

    @classmethod
    @with_defaults(
        preview=Fragment(
            lambda field, **_: field.value,
            tag="a",
            attrs__href=lambda field, **_: field.value.url if field.value.url else None,
        ),
    )
    def link(cls, **kwargs):
        return cls(**kwargs)

    @classmethod
    @with_defaults(
        preview=Fragment(  # probably not Fragment, it creates paired tag
            tag="img",
            attrs__src=lambda field, **_: field.value.url if field.value.url else None,
        ),
    )
    def img(cls, **kwargs):
        return cls(**kwargs)

and then add it to @with_defaults of Field.file and Field.image, and probably to the image_row.html

that way you can use Style to make it pretty and you can easily change attrs and template

but I'm not able to make a PR for that, I'm not that familiar with iommi yet :)