| | 337 | def _child(self, *parents): |
| | 338 | model_parents = tuple(self.model._meta.parents.keys()) |
| | 339 | if not model_parents: |
| | 340 | raise ValueError("%r is not a child model; it has no parents" |
| | 341 | % self.model) |
| | 342 | attrs = {} |
| | 343 | for parent in parents: |
| | 344 | if not isinstance(parent, model_parents): |
| | 345 | raise ValueError("%r is not a parent instance of %r" |
| | 346 | % (parent, self.model)) |
| | 347 | for field in parent._meta.fields: |
| | 348 | if field.name not in attrs: |
| | 349 | attrs[field.name] = getattr(parent, field.name) |
| | 350 | attrs[self.model._meta.parents[parent.__class__].name] = parent |
| | 351 | return attrs |
| | 352 | |
| | 353 | def prepare_child(self, *parents): |
| | 354 | """ |
| | 355 | Creates and returns a new object with the given model instances as |
| | 356 | parents. The object is *not* saved to the database. |
| | 357 | """ |
| | 358 | assert parents, \ |
| | 359 | "prepare_child() must be passed at least one parent instance" |
| | 360 | attrs = self._child(*parents) |
| | 361 | return self.model(**attrs) |
| | 362 | |
| | 363 | def create_child(self, *parents, **kwargs): |
| | 364 | """ |
| | 365 | Creates a new object with the given model instances as parents, updates |
| | 366 | it with the given kwargs, saves it to the database, and returns the |
| | 367 | created object. |
| | 368 | """ |
| | 369 | assert parents, \ |
| | 370 | "create_child() must be passed at least one parent instance" |
| | 371 | attrs = self._child(*parents) |
| | 372 | attrs.update(kwargs) |
| | 373 | obj = self.model(**attrs) |
| | 374 | obj.save() |
| | 375 | return obj |
| | 376 | |