So I just tested one thing, making the following tables.
# Dump of table driverclass
# ------------------------------------------------------------
CREATE TABLE `driverclass` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
# Dump of table event
# ------------------------------------------------------------
CREATE TABLE `event` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
# Dump of table driver
# ------------------------------------------------------------
CREATE TABLE `driver` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
# Dump of table driver_driverclass_event
# ------------------------------------------------------------
CREATE TABLE `driver_driverclass_event` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`driver_id` int(11) unsigned DEFAULT NULL,
`event_class_id` int(11) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `driver_id` (`driver_id`),
KEY `event_class_id` (`event_class_id`),
CONSTRAINT `driver_driverclass_event_ibfk_2` FOREIGN KEY (`event_class_id`) REFERENCES `driverclass_event` (`id`),
CONSTRAINT `driver_driverclass_event_ibfk_1` FOREIGN KEY (`driver_id`) REFERENCES `driver` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
# Dump of table driverclass_event
# ------------------------------------------------------------
CREATE TABLE `driverclass_event` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`event_id` int(11) unsigned DEFAULT NULL,
`driverclass_id` int(11) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `event_id` (`event_id`),
KEY `driverclass_id` (`driverclass_id`),
CONSTRAINT `driverclass_event_ibfk_2` FOREIGN KEY (`driverclass_id`) REFERENCES `driverclass` (`id`),
CONSTRAINT `driverclass_event_ibfk_1` FOREIGN KEY (`event_id`) REFERENCES `event` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Which should be relations in terms of ManyToManyField
. However, Djangos
inspectdb
looked at it as 5 models with tons of ForeignKeys. Doesn't Djangos
inspectdb
take ManyToManyFields into account, or is my databasemodel wrong?
Your database schema appears to be alright. However Django doesn't automatically create Many-To-Many fields as you have found out. The models for driverclass_event and ** driver_driverclass_event** are a so-called 'through' models. Normally you would also define ManyToManyField on both ends of the relationship and specify the correct 'through' model:
class Event(db.Model):
pass
class DriverClass(db.Model):
events = db.ManyToManyField(Event, through='DriverClassEvent')
class DriverClassEvent(db.Model):
driver_class = db.ForeignKeyField(DriverClass)
event = db.ForeignKeyField(Event)
See also: https://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationships
Normally through models are used when you want to store information about the relationship, like the start date of the relationship or to refer to this relationship using a foreign key. In your example, you store which drivers have a relationship to a DriverClassEvent. So DriverClassEvent should have a model to be able to refer to it.
class DriverDriverClassEvent(db.Model):
driver = db.ForeignKeyField(Driver)
driver_class_event = db.ForeignKeyField(DriverClassEvent)
class Driver(db.Model):
driver_class_events = db.ManyToManyField(DriverClassEvent, through='DriverDriverClassEvent')
Now you could drop the DriverDriverClassEvent as you don't store any data about that relationship, or refer to the relationship in other models. So the last example becomes*:
class Driver(db.Model):
driver_class_events = db.ManyToManyField(DriverClassEvent, db_table='driver_driverclass_event')
* Note that you don't have control over the field names, so those would have to match to Django's auto-generated field names.