在一个字段中处理多个ForeinKeys _ Django

时间:2019-01-29 08:59:22

标签: django django-models

假设我们有一个模型A,它与模型B的关系为ForeinKey。

lazy val commonSettings  = Seq(  
organization := "com.example",
  version := "0.0.1-SNAPSHOT",
  scalaVersion := "2.11.12",
resolvers ++= Seq(
    "Apache Development Snapshot Repository" at "https://repository.apache.org/content/repositories/snapshots/",
    "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/",
    Resolver.mavenLocal
  ),
assemblyMergeStrategy in assembly := {
    case PathList("META-INF", xs @ _*) => MergeStrategy.discard
    case x => MergeStrategy.first
  },
libraryDependencies ++= commonDependencies ++ testingDependencies)
lazy val sharedProject = (project in file(...))
.settings(commonSettings: _*)
val projectA = .....dependsOn(sharedPorject)
val projectB = .....dependsOn(sharedPorject)

我如何拥有一个具有数十个 foo 的A模型的实例?以及我需要的适当解决方案。那可能吗? 我认为,如果我们创建了许多foo字段,那就太好了。那么在django中可以处理这类问题吗?

1 个答案:

答案 0 :(得分:2)

您的问题尚不清楚,但是我将尝试回答我想到的两种情况。

如果将B分配给A的每个目的都不同(并且数量有限)

例如,如果B代表人而A代表书,则可能是这种情况。现在,您需要具有例如以下字段:书籍作者,书籍出版者,书籍翻译者等。在这种情况下,您应该只创建多个外键。但是有一个陷阱……Django默认在您要引用的模型中创建虚拟字段,因此您可以遍历您的关系。该字段以类命名,您从中引用模型,在此示例中,其命名为a_set。不幸的是,对于每个关系,该字段的名称都完全相同,因此它们会发生冲突。

该问题的解决方案是明确指定该虚拟字段的名称:

class B(models.Model):
.....

class A(models.Model):
    author = models.ForeinKey(B, related_name='books_written')
    publisher = models.ForeinKey(B, related_name='books_published')
    translator = models.ForeinKey(B, related_name='books_translated')

或者您可以禁用这些反向字段:

class B(models.Model):
.....

class A(models.Model):
    author = models.ForeinKey(B, related_name='+')
    publisher = models.ForeinKey(B, related_name='+')
    translator = models.ForeinKey(B, related_name='+')

如果BA的每个分配都应具有(大致)相同的目的,或者您无法指定其中有多少。

例如,在以前的情况下,A代表书籍,B代表人物,而您要做的就是将多位作者分配到一本书,则可能会发生这种情况。在这种情况下,您应该在这两个模型之间创建多对多关系。 Django为此提供了https://i.imgur.com/uY8Mq0S.png字段,其用法非常简单:

class B(models.Model):
.....

class A(models.Model):
    authors = models.ManyToManyField(B)

如果出于任何原因您希望在这两个模型之间具有多个多对多关系,则与第一种情况一样,也会发生虚拟反向关系字段冲突的问题。修复该问题是等效的。

此外,您可以通过创建第三个模型来创建它们之间的外键,而无需使用ManyToManyField来自己创建该关系(这就是Django在后台使用时所做的工作)该字段)。您甚至可以使用ManyToManyField并使用该字段的through参数来注册该模型,以具有直接关系和反向关系字段,以便于使用。