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.

Reply via email to