flask-restless
flask-restless copied to clipboard
Allow custom DELETE logic
In many cases, one might not want DELETE calls to actually issue a deletion of the record from the database, instead it would be desirable to set an is_deleted attribute to True or something similar.
Currently flask-restless does not seem to allow this, which makes it too rigid to be used in critical applications like financial software, where persistent deletion of records is very uncommon.
This is a good idea, I think.
However, this would require the user to write the entire code, thereby making Flask-Restless essentially pointless for this particular HTTP method. If we allowed that, would it make sense to allow the user to specify entirely customized code for every method?
Well, that would certainly be a good start. We already have the request preprocessors and postprocessors, an optional processor override would be great. I don't think it'd draw Flask-Restless useless for several reasons:
- There are still all the other methods
- There is still the regular DELETE for the models that don't require soft deletion
- Flask-Restless still imposes good RESTful practice
Right now I'm having to write a custom SQLAlchemy session and a custom Base-derived model to inherit my models from, and it's too much effort for what could have been a single simple function.
Another way to approach this would be to have the user put all the custom code in the preprocessor, and then not actually process the default deletion if the custom preprocessor returns False or something.
I don't like that alternate approach, it seems too...complicating from the user's perspective. Swapping out processing functionality is, I suppose, cleaner, both intuitively and from an implementation perspective. I guess also that this generalizes the current default functionality, which could then simply be provided as the default "processing" function. However, then we lose some of the value (the simplicity) of having a single class-based implementation. Another tradeoff...
I agree on swapping out processing functionality.
Do you want me to refactor it for myself, then submit a pull request, or would you prefer this to be developed in some other way?
Another problem of course is, once you do the custom DELETE, then you have to do the custom GET for the listings, since you don't want entries where is_deleted = True to be fetched in the listing.
How to automate this reasonably? I have no idea at this point.
I am interested in custom implementation of some methods too. What about decorators within the model?
from flask.ext.restless import override
[...]
class User(Base):
[...]
@override('DELETE')
def my_custom_delete([... something here?]):
pass
@Diaoul I prefer for the model definition to be independent of (the controller) Flask-Restless.
@sssilver How about for now providing a much smaller level of customization to the user. For example:
manager.create_api(MyModel, methods=['GET', 'DELETE'], on_delete_set_attr='is_deleted')
If the keyword argument on_delete_set_attr
is not set, then do what we are doing currently. If it is set to the string 'is_deleted'
, then do setattr(MyModel, 'is_deleted', True)
.
In my case, I have an Icon model that has a path column. I'd like the file pointed by the path column to be deleted too in case the model gets deleted. It seemed to me that the "model" was the proper place for this logic in OOP but I'm open to alternative implementations.
+1 for implementing this functionality. I think that maybe allowing overriding the default behaviour by passing custom functions to the api manager constructor would fit better the current way things are done (pre and post processor, enabled methods, included methods, are all provided that way)
+1 for changes to enable soft deletes.
+1 for allowing a generic override of a method. I've found myself wanting this several times.
If the default behaviour was exposed, then the current pre- and post- processor customisations could be replaced by the method override, where you can do whatever you like before and/or after calling the default method implementation.
Is there any plan to implement this?
I've had to work around this for soft DELETEs by doing it in the preprocessor method then doing:
raise ProcessingException(code=200)
to prevent any further processing. This is a really hacky workaround and I'd much prefer to have an officially supported way of overriding methods.
Any info ?
Is there any plan to implement this?
I've had to work around this for soft DELETEs by doing it in the preprocessor method then doing:
raise ProcessingException(code=200)
to prevent any further processing. This is a really hacky workaround and I'd much prefer to have an officially supported way of overriding methods.
I like this idea, but the code should be 204 for a successfully deletion right?