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

查看:142
本文介绍了Django-根据其内容引用两个表之一的外键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的数据库模型设计陷入僵局,可以寻求帮助。
我们正在使用Postgres数据库和django框架来存储各种论文,书籍等。

I've hit a dead end in my database-model design and could use some help. We are using a Postgres database and django framework to store a variety of papers, books etc.

这些是我遇到麻烦的基类:

These are the base classes I'm having trouble with:

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类被建模为将编辑者存储为相应书的人物,例如。 Ryan Carey或 Nicholas Rowe。
Publisher类将包含芝加哥大学出版社之类的信息。

The Editor class above is modeled to store the editor(s) as persons of a corresponding book eg. "Ryan Carey" or "Nicholas Rowe". The Publisher class would hold information like "University of Chicago Press".

如果编辑者和发布者相同,则会出现问题。
例如,编辑者和出版者都应该是芝加哥大学出版社。

The problem hatches should the Editor and Publisher be the same. For example should the Editor and Publisher both be "University of Chicago Press".

现在,每当将新书通过django-保存到数据库时,管理界面我想执行以下操作:

Now, whenever a new Book is saved to the database through the django-admin interface I would like following to happen:


  • 如果指定了一个或多个编辑器,则将其保存为上面的模型。
  • >
  • 如果未给出编辑器但给出了发布者,则使编辑者指向发布者指向的相同密钥

  • 如果两者均未给出,则将两者都留为空白

  • If one or more Editors are given, save it as in the model above.
  • If no Editors are given but a Publisher is given then make editors point to the same key publisher is pointing to
  • If none of both are given leave both blank

我正在考虑以某种方式实现它:

I was thinking of implementing it somehow like this:

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位也许可以通过继承进行固定,但是仍然有简单的编辑器和一个发布者,我不希望将发布者和编辑器存储在同一张表中。

The self.editors = self.publisher bit could perhaps be fixed with inheritance, but there are still multiple editors and just one publisher and I dont want publishers and editors to be stored int he same table.

有人想过如何解决这个问题?

Any thoughts on how to approach this?

推荐答案

几乎不需要重新构建模型,就可以并且比现在更灵活。

With little of re-structuring your models, is possible and will be more flexible than now.

首先:不要将发布者和编辑者置于2个单独的模型中。制作一个。

First: don't put publisher and editor to 2 separate models. Make one.

第二个:如果您可以同时拥有个人和组织/公司的发布者/编辑者(这将需要不同的模型字段),请将所有公共字段放入一个模型中并制作2个将从该模型继承的模型,其中包含更多指定字段。

Second: if you can have publisher/editor both person and organization/company (and that will require different model fields), put all common fields into one model and make 2 models that will inherit from that model, containing more specified fields. That will create under the hood one-to-one relation between fields.

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

Third: create 2 fields in your book model, one ForeignKey named publisher and one ManyToMany named editors. Both relations should point to your base model for publisher/editor.

示例代码:

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.

这篇关于Django-根据其内容引用两个表之一的外键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆