2

所以我只测试了一件事,制作了下表。

# 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;

这应该是关系ManyToManyField。但是,Djangos inspectdb将其视为具有大量 ForeignKeys 的 5 个模型。没有Djangos inspectdb考虑 ManyToManyFields,还是我的数据库模型错了?

4

1 回答 1

5

您的数据库架构似乎没问题。但是,Django 不会自动创建您发现的多对多字段。driverclass_event和** driver_driverclass_event**的模型是所谓的“通过”模型。通常,您还会在关系的两端定义ManyToManyField并指定正确的“通过”模型:

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)

另请参阅:https ://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationships

当您想要存储有关关系的信息时,通常使用直通模型,例如关系的开始日期或使用外键引用此关系。在您的示例中,您存储哪些驱动程序与DriverClassEvent有关系。所以DriverClassEvent应该有一个模型可以引用它。

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')

现在您可以删除DriverDriverClassEvent,因为您不存储有关该关系的任何数据,或者在其他模型中引用该关系。所以最后一个例子变成*:

class Driver(db.Model):
    driver_class_events = db.ManyToManyField(DriverClassEvent, db_table='driver_driverclass_event')

* 请注意,您无法控制字段名称,因此这些名称必须与 Django 自动生成的字段名称相匹配。

于 2013-08-06T07:23:14.123 回答