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
-~----------~----~----~----~------~----~------~--~---

Reply via email to