On 10/02/2019 6:22 pm, Nick Emery wrote:
> I am trying to wrap up my first app using Django (specifically Django
> Rest Framework which may change the save behavior), but have run into
> an issue that I haven't been able to solve for about 10 hours now.
>
> I am trying to override the save() method of a model to modify a field
> on a bunch of child objects when it is created; however, I can't
> figure out /any/ way get the objects or ids for the children.
>
> My code looks something like:
I usually have a couple of methods to simplify save operations like this ...
def save(self, *args, **kwargs):
results = self._pre_save(self)
super(Parent, self).save(*args, **kwargs)
self._post_save(self, results)
Much easier for me to "see" what I'm doing.
In your case if orphans exist, how do you identify them as now related
to a new Parent? Perhaps a query looking for parent=None.
From what I understand of your use case you would need to select a
Child when creating a Parent. That sounds like a field widget to perform
that query before the Parent is first saved. If so, the Child object
would be available to _pre_save() but the Parent still does not yet
exist and Parent.id is still None so you can't populate the Child FK.
Parent.id is however available to _post_save() so if the Child object is
passed from _pre_save() via results (above) then _post_save can populate
its FK with self and just save the Child object to complete the deal.
The relationship is the foreign key which means the Child can have only
one Parent which doesn't yet exist. So it feels like a sky hook.
Parents and children (as data) are person objects with virtually
identical attributes. The interesting information is in the relationship
for which a foreign key seems too restrictive. Have you considered a
"through" table thus making a many-to-many relationship? That table can
carry heaps of information about the relationship and is very flexible.
For example, the child can now have two parents.
When a "through" record is created to establish a relationship
(selectable from a choices list), both parent and child already exist
which lets you delegate a fair bit of processing to the "though" model
save() method which in real world timing is probably where it belongs. I
prefer it because I can use queries rather than widgets.
Not sure if this helps
Mike
> |
> classParent(models.Model):
> """When I create this, I want the children to be modified."""
> defsave(self,*args,**kwargs):
>
ifnotself.pk <
http://self.pk/>:
> self._begin(*args,**kwargs)
> else:
> super(Parent,self).save(*args,**kwargs)
>
> def_begin(self,*args,**kwargs):
> super(Parent,self).save(*args,**kwargs)
> print(self.child_set.all())# --> This gives: "<QuerySet []>"
> for i in self.child_set.all():
> i.last_name = self.last_name
> i.save()
>
> last_name =models.CharField(max_length=100)
>
>
> classChild:
> parent =models.ForeignKey(
> 'Parent',
> on_delete=models.SET_NULL,
> null=True,
> )
> last_name =models.CharField(max_length=100)
> |
>
> ANY way to modify the children when the parent is saved would be a
> life saver (even if hacky or sub-optimal).
> --
> You received this message because you are subscribed to the Google
> Groups "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to
django-users...@googlegroups.com
> <mailto:
django-users...@googlegroups.com>.
> <mailto:
django...@googlegroups.com>.
> <
https://groups.google.com/d/msgid/django-users/24c7156b-6873-4cd3-952e-dc819fa72be0%40googlegroups.com?utm_medium=email&utm_source=footer>.