MCPcopy Create free account
hub / github.com/Tencent/CodeAnalysis / clone

Method clone

server/projects/analysis/apps/base/basemodel.py:183–238  ·  view source on GitHub ↗

Clone this instance and return the new, cloned instance. ``overrides`` should be a dictionary of override values for fields on the cloned instance. M2M or reverse FK relations listed in ``cascade`` iterable will be cascade-cloned. By default, if not listed in

(self, cascade=None, overrides=None, user=None)

Source from the content-addressed store, hash-verified

181 return super(CDBaseModel, self).save(*args, **kwargs)
182
183 def clone(self, cascade=None, overrides=None, user=None):
184 """
185 Clone this instance and return the new, cloned instance.
186 ``overrides`` should be a dictionary of override values for fields on
187 the cloned instance.
188 M2M or reverse FK relations listed in ``cascade`` iterable will be
189 cascade-cloned. By default, if not listed in ``cascade``, m2m/reverse
190 FKs will effectively be cleared (as the remote object will still be
191 pointing to the original instance, not the cloned one.)
192 If ``cascade`` is a dictionary, keys are m2m/reverse-FK accessor names,
193 and values are a callable that takes the queryset of all related
194 objects and returns those that should be cloned.
195 """
196 if cascade is None:
197 cascade = {}
198 else:
199 try:
200 cascade.iteritems
201 except AttributeError:
202 cascade = dict((i, lambda qs: qs) for i in cascade)
203
204 if overrides is None:
205 overrides = {}
206
207 overrides["created_time"] = utcnow()
208 overrides["creator"] = user
209 overrides["modifier"] = user
210
211 clone = self.__class__()
212
213 for field in self._meta.fields:
214 if field.primary_key:
215 continue
216 val = overrides.get(field.name, getattr(self, field.name))
217 setattr(clone, field.name, val)
218
219 clone.save(force_insert=True)
220
221 for name, filter_func in cascade.items():
222 mgr = getattr(self, name)
223 if mgr.__class__.__name__ == "ManyRelatedManager": # M2M
224 clone_mgr = getattr(clone, name)
225 existing = set(clone_mgr.all())
226 new = set(filter_func(mgr.all()))
227 clone_mgr.add(*new.difference(existing))
228 clone_mgr.remove(*existing.difference(new))
229 elif mgr.__class__.__name__ == "RelatedManager": # reverse FK
230 reverse_name = getattr(self.__class__, name).related.field.name
231 for obj in filter_func(mgr.all()):
232 obj.clone(overrides={reverse_name: clone})
233 else:
234 raise ValueError(
235 "Cannot cascade-clone '{0}'; "
236 "not a many-to-many or reverse foreignkey.".format(name))
237
238 return clone
239
240 def delete(self, user=None, permanent=False):

Callers

nothing calls this directly

Calls 5

utcnowFunction · 0.70
getMethod · 0.45
saveMethod · 0.45
allMethod · 0.45
removeMethod · 0.45

Tested by

no test coverage detected