On Wed, 2009-03-11 at 19:21 -0700, Margie wrote: > I have a Tile model that contains a foreign to a Chip: > > class Tile(models.Model): > name=models.CharField(max_length=NAME_LENGTH) > chip = models.ForeignKey(Chip) > > I find that I get an integrity error if I create a tile that refers to > a chip that has not yet been saved: > > >>> c = Chip(name="chip") > >>> t = Tile(name="tile", chip=c) > >>> t.save() > [stack trace omitted] > IntegrityError: chipvision_tile.chip_id may not be NULL > > This is reasonable. So I then saved the chip and then tried to save > the tile, but I still get the integrity error: > >>> c.save() > >>> t.chip > <Chip: xchip> > >>> t.chip.id > 5 > >>> t.save() > [stack trace omitted] > IntegrityError: chipvision_tile.chip_id may not be NULL
There are some implementation details going on here and we should probably try to raise an error a bit earlier. The behaviour is expected and the solution is to not assign unsaved objects. What's going on, if you care, is that there are two attributes involved. The t.chip attribute is a copy of the Python object (the Chip instance). The t.chip_id attribute holds the value of foreign key and when you first assigned to t.chip, t.chip_id was set to None. That "None" isn't a reference to anything, so when t.chip was updated (since it's a reference), the t.chip_id value was not. There are a couple of potential things Django could do better here, including resetting the chip_id value just before saving (a little risky -- I think I worked out a way to do stupid things once, but I can't remember what it is now) or just reporting an error when you wrote t.chip = chip originally. Regards, Malcolm > > However, if I then reset the chip field of the tile (just by > reassigning t.chip = t.chip) and then save the tile, the save now > works fine: > > >>> t.chip = t.chip > >>> t.save() # this save works! That's because setting the 'chip' attribute calls a setter method that also updates t.chip_id. Odd if you don't realise what's going on. Consistent in an implementation sense, but, as I mention, we can do better. Regards, Malcolm --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---