I don't quite understand what you did there, but, it seems to me it is the same thing with your initial post.
ref = getattr(self, f.name) -> you are getting a field here, this field is a empty descriptor, doesn't hold any data yet. ref.full_save(*args,*kwargs) -> you populated your field with data here by calling full_save on it setattr(self,f.name,ref) -> you are assigning this field to be a part of parent object, where you got it initially then you are saving the parent object. 2011/8/19 David Jacquet <jacquet.da...@gmail.com> > > Thanks Yaşar and Jani for your fast replies! > > > I understand that normally one would assign in the reverse order. However I > do not understand exactly what happens when I do > meeting.place = meeting.place > never in my programming experience have I seen an example when > x=x > really does something. Isn't this strange? > > > Anyway, the reason for me wanting to go around normal behavior is that I > have a quite complicated and nested datamodel. Then I offer an api where > people can post JSON object. The will posts will be heavily nested ojbects > and I do not want save it to db by rewriting the whole save-chain in my > code. I have solved this by creating the class AREM below. When I have a > dictionary d representing a class A (subclass to AREM) and I want it saved I > do: > > a = A().from_dict(d) > a.full_save() > > I have gotten it to work, but not before I added the (for me very strange) > row > > setattr(self, f.name, ref) #Without this everything collapses > > residing on the second most bottom row in the code below. The problem is > that I do not know what it does, nor if there is a more elegant, faster or > better way to do it. > > Best Regards > David > > > > #class AbstractRecursiveEnabledModel(models.Model): > class AREM(AMCS): > class Meta: > abstract = True > > def from_dict(self, d): > if not isinstance(d, dict): > return d > fl = self._meta.fields > for f in fl: > if d.has_key(f.name) and f.rel and d[f.name] is not None: > d[f.name] = f.rel.to().from_dict(d[f.name]) > self.__init__(**d) > return self > > def full_save(self,*args, **kwargs): fl = self._meta.fields > > for f in fl: > if f.rel: > ref = getattr(self, f.name) > if ref is not None and ref.pk is None and ref is not self: > ref.full_save(*args, **kwargs) > setattr(self, f.name, ref) #Without this everything > collapses > super(AREM, self).save(*args, **kwargs) > > > > > > > > On Fri, Aug 19, 2011 at 2:34 PM, Jani Tiainen <rede...@gmail.com> wrote: > >> On 08/19/2011 03:15 PM, Jacco wrote: >> >>> I am having great difficulties in saving nested models in an easy >>> way. >>> >>> >>> #Two (almost) identical functions: >>> def test1(): >>> place = Place(where='Paris') >>> >> >> place is not saved, thus it does not have a primary key (id) >> >> >> meeting = Meeting(place=place, when='2011-01-01') >>> >> >> You assign non saved instance to a meeting. Probably what happened >> internally is that place.pk is copied to meeting.place_id. >> >> place.save() >>> >> >> You saved place. Changes in model are not reflected to referred model. >> >> meeting.save() >>> >> >> You save meeting with still (partially) stale place pk. thus resulting an >> exception. >> >> >> def test2(): >>> place = Place(where='Paris') >>> meeting = Meeting(place=place, when='2011-01-01') >>> >>> place.save() >>> meeting.place = meeting.place #BY setting meeting.place to >>> itself, it works !!!!!!!!!!!! >>> >> >> You updated your meeting internal structure. >> >> meeting.save() >>> return meeting >>> >>> ---------------------------------------------------------------------------------------------------------------------------------------------- >>> >>> >>> >>> - Running test1() results in crash "null value in column "place_id" >>> violates not-null constraint" >>> - Running test2() results in OK. >>> - Only difference is the dummy line "meting.place = meeting.place". >>> >>> Could someone who really understands this explain what is going on? >>> >>> >> What's going on that you have done it incorrect order. >> >> place = Place(where='Paris') >> place.save() # Place saved, PK assigned. >> >> >> meeting = Meeting(place=place, when='2011-01-01') >> meeting.save() # Meeting saved with correct place. >> >> -- >> >> Jani Tiainen >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Django users" group. >> To post to this group, send email to django-users@googlegroups.com. >> To unsubscribe from this group, send email to >> django-users+unsubscr...@googlegroups.com. >> For more options, visit this group at >> http://groups.google.com/group/django-users?hl=en. >> >> > -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To post to this group, send email to django-users@googlegroups.com. > To unsubscribe from this group, send email to > django-users+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/django-users?hl=en. > -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.