I am using multi-table inheritance in the latest version from SVN (r7573), and I want a child class to have two OneToOneFields?: one to the parent class as the primary-key parent link (the default created one with a primary key), and another to the parent class representing a different relation (which is not a primary key).
For example, a Restaurant is a Place, so it has a parent link to Place, but it also has one kitchen (which could be a place):
class Place(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
class Restaurant(Place):
serves_pizza = models.BooleanField()
kitchen = models.OneToOneField(Place, related_name='restaurant_i_am_the_kitchen_of')
This shouldn't make kitchen_id a primary key, but it does (even if I set primary_key=False explicitly). It generates the following SQL:
BEGIN;
CREATE TABLE `cms_place` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`name` varchar(50) NOT NULL,
`address` varchar(80) NOT NULL
)
;
CREATE TABLE `cms_restaurant` (
`serves_pizza` bool NOT NULL,
`kitchen_id` integer NOT NULL UNIQUE PRIMARY KEY
)
;
ALTER TABLE `cms_restaurant` ADD CONSTRAINT kitchen_id_refs_id_c2a98e0 FOREIGN KEY (`kitchen_id`) REFERENCES `cms_place` (`id`);
COMMIT;
This behavior of making every OneToOneField? that goes to a parent class a primary key happens in django/db/models/base.py on line 98-101:
if base in o2o_map:
field = o2o_map[base]
field.primary_key = True
new_class._meta.setup_pk(field)
If I disable this and force it go to to the else clause (by making it 'if False'), then I get the desired SQL:
BEGIN;
CREATE TABLE `cms_place` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`name` varchar(50) NOT NULL,
`address` varchar(80) NOT NULL
)
;
CREATE TABLE `cms_restaurant` (
`place_ptr_id` integer NOT NULL UNIQUE PRIMARY KEY,
`serves_pizza` bool NOT NULL,
`kitchen_id` integer NOT NULL UNIQUE
)
;
ALTER TABLE `cms_restaurant` ADD CONSTRAINT place_ptr_id_refs_id_c2a98e0 FOREIGN KEY (`place_ptr_id`) REFERENCES `cms_place` (`id`);
ALTER TABLE `cms_restaurant` ADD CONSTRAINT kitchen_id_refs_id_c2a98e0 FOREIGN KEY (`kitchen_id`) REFERENCES `cms_place` (`id`);
COMMIT;
It seems that lines 98-101 shouldn't just check that the base class is in the o2o_map, but it should also check that the OneToOneField? has parent_link set to True.