Dear Awesome Community Members, There is an issue with the copy method of the ModelStorage class that I would like to discuss and propose a solution to.
*The issue* If the model contains a field, other than id, that is marked UNIQUE, ModelStorage.copy will fail unless you override the copy method and handle it somehow. The original ModelStorage.copy method fetches the records from storage before copying and uses an internal method to cycle through the fields. I can't override that internal method and I can't influence the fields that get seen/handled. see: http://hg.tryton.org/trytond/file/6d0a37198947/trytond/model/modelstorage.py#l248 *Observations and Use-Cases* Line 293 ( http://hg.tryton.org/trytond/file/6d0a37198947/trytond/model/modelstorage.py#l293 ) removes the id field from the data to be written to the new record. This is because we know it's unique and will be automatically generated. res.group has faced this problem. Based on http://hg.tryton.org/trytond/file/6d0a37198947/trytond/res/group.py#l55 the work around was to override the copy method and call super(Group, cls).copy on records one by one. In my case, I have one field that is read only and gets a value from a default_fieldname staticmethod and, on another model, there is a field that gets its value calculated by the overridden create classmethod. *Proposed Solutions* There are a couple of ways that this can be fixed in Trytond core. 1. If there's a way to detect if fields are UNIQUE, we can also check if they're in cls._defaults and just remove them from the copy like is done for the id field. This is only a partial solution however. 2. We could allow that the values for default argument to the copy method include callables. The callable would take the record instance as a single argument and return a value for the field 3. Add a third argument to ModelStorage.copy which is a list of fields to exclude Solution 2 would simplify the override that is done in subclasses like res.group. Solution 3 would simplify my use cases to just a call to super(ModelName, cls).copy(records, exclude=['uniqe1', 'uniq2']) Solution 1 would be nice, but I don't know how easy it would be. Plus, if we have 2 or 3, we can skip it. Comments please. --- MM -- You received this message because you are subscribed to the Google Groups "tryton-dev" group. To view this discussion on the web visit https://groups.google.com/d/msgid/tryton-dev/b3ecf627-c52b-4e64-a64a-c456ee1347f7%40googlegroups.com.