Django-外键根据其内容引用两个表中的一个[英] Django - Foreign key referencing one of two tables depending on its content

本文是小编为大家收集整理的关于Django-外键根据其内容引用两个表中的一个的处理方法,想解了Django-外键根据其内容引用两个表中的一个的问题怎么解决?Django-外键根据其内容引用两个表中的一个问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我在我的数据库模型设计中遇到了死胡同,需要一些帮助.我们使用 Postgres 数据库和 django 框架来存储各种论文、书籍等.

这些是我遇到问题的基类:

class Publisher(models.Model):
    name = models.CharField(unique=True)
    website = models.URLField(blank=True)
    #...

class Editor(models.Model):
    firstname = models.CharField()
    lastname = models.CharField()
    #...

class Book(models.Model):
    title = models.CharField(unique=True)
    #...
    editors = models.ManyToManyField(Editor, blank=True)
    publisher = models.ForeignKey(Publisher, blank=True)
    #...

上面的 Editor 类被建模为将编辑器存储为相应书籍的人员,例如."瑞恩凯莉"或"尼古拉斯罗".Publisher 类将保存诸如"芝加哥大学出版社"之类的信息.

如果 Editor 和 Publisher 相同,问题就会出现.例如,Editor 和 Publisher 是否应该都是"芝加哥大学出版社".

现在,每当通过 django-admin 界面将新书保存到数据库时,我希望发生以下情况:

  • 如果给定了一个或多个编辑器,请将其保存在上面的模型中.
  • 如果没有给出编辑者但给出了发布者,则让编辑者指向同一个发布者指向的关键
  • 如果两者都没有给出,则都留空

我想以某种方式实现它:

class Book:
#...
    def save(self, *args, **kwargs):
        if self.editors.count() <= 0 and self.publisher:
            self.editors = self.publisher #This is not possible
        super(Book, self).save(*args, **kwargs)

self.editors = self.publisher 位也许可以通过继承来修复,但仍然有多个编辑器和一个发布者,我不希望发布者和编辑器存储在同一个表中.

关于如何解决这个问题的任何想法?

推荐答案

几乎不需要重构你的模型,这是可能的,而且会比现在更灵活.

首先:不要将发布者和编辑者放在 2 个不同的模型中.做一个.

第二:如果您可以同时拥有个人和组织/公司的发布者/编辑者(这将需要不同的模型字段),则将所有公共字段放入一个模型中,并创建两个将从该模型继承的模型,包含更多指定的字段.这将在后台创建字段之间的一对一关系.

第三:在你的书本模型中创建 2 个字段,一个名为 publisher 的 ForeignKey 和一个名为 editors 的 ManyToMany.两种关系都应指向您的发布者/编辑者的基本模型.

示例代码:

class PEBase(models.Model): # have no idea how to name it better

    some_common_field = models.Field(...)


class PEPerson(PEBase):

    first_name = models.CharField()
    last_name = models.CharField()


class PEOrganization(PEBase):

    name = models.CharField()
    website = models.URLField()


class Book(models.Model):

    title = models.CharField(unique=True)
    #...
    editors = models.ManyToManyField(PEBase, blank=True, related_name="books_edited")
    publisher = models.ForeignKey(PEBase, blank=True, related_name="books_published")

    def save(self, *args, **kwargs):
        super(Book, self).save(*args, **kwargs)
        if self.editors.count() <= 0 and self.publisher:
            self.editors.add(self.publisher) #This must go after save - ID of book must be already set.

本文地址:https://www.itbaoku.cn/post/1764201.html