Django对象扩展/一对一关系问题

2 投票
2 回答
750 浏览
提问于 2025-04-16 02:06

你好!我正在把一个内部系统迁移到Django上,遇到了一些问题。

介绍
我们现在的系统是一个账单系统,能够跟踪复式记账,同时允许用户输入数据,比如发票、费用等。

基础对象
我有两个基础对象/模型:

  • JournalEntry(记账条目)
  • JournalEntryItems(记账条目项)

它们的定义如下:

class JournalEntry(models.Model):
    gjID = models.AutoField(primary_key=True)
    date = models.DateTimeField('entry date');
    memo = models.CharField(max_length=100);

class JournalEntryItem(models.Model):

    journalEntryID = models.AutoField(primary_key=True)
    gjID = models.ForeignKey(JournalEntry, db_column='gjID')
    amount = models.DecimalField(max_digits=10,decimal_places=2)

到目前为止,一切都很好。在管理后台运行得非常顺利(内联功能正常等)。

接下来。
然后我们还有两个模型:

  • InvoiceEntry(发票条目)
  • InvoiceEntryItem(发票条目项)

InvoiceEntry是JournalEntry的一个扩展,所以我使用了一个OneToOneField(这是我们当前网站后台使用的方式)。这也运行得很顺利。

class InvoiceEntry(JournalEntry):
    invoiceID = models.AutoField(primary_key=True, db_column='invoiceID', verbose_name='')
    journalEntry = models.OneToOneField(JournalEntry, parent_link=True, db_column='gjID')
    client = models.ForeignKey(Client, db_column='clientID')

    datePaid = models.DateTimeField(null=True, db_column='datePaid', blank=True, verbose_name='date paid')

我遇到问题的地方是,当我尝试将一个InvoiceEntryItem(它继承自JournalEntryItem)添加到与InvoiceEntry相关的内联时,出现了错误:

<class 'billing.models.InvoiceEntryItem'> has more than 1 ForeignKey to <class 'billing.models.InvoiceEntry'>

我认为,InvoiceEntryItem直接有一个指向InvoiceEntry的外键。同时,它通过JournalEntry与JournalEntryItems的1对多关系间接地也有一个外键指向InvoiceEntry。

这是我目前使用的代码。

class InvoiceEntryItem(JournalEntryItem):
    invoiceEntryID = models.AutoField(primary_key=True, db_column='invoiceEntryID', verbose_name='')
    invoiceEntry = models.ForeignKey(InvoiceEntry, related_name='invoiceEntries', db_column='invoiceID')
    journalEntryItem = models.OneToOneField(JournalEntryItem, db_column='journalEntryID')
  1. 我尝试去掉journalEntryItem的OneToOneField。这样做后,我就无法获取这个特定InvoiceEntryItem的金额(这个金额只存储在journalEntryItem中)。

  2. 我也尝试去掉invoiceEntry的外键关系。这样做后,我就无法在管理后台的内联中看到InvoiceEntry与InvoiceEntryItems的1对多关系。所有字段都是空的(而不是当前数据库中实际存储的数据)。

看起来第二个选项更接近我想要的。但由于我对Django的不熟悉,似乎限制了我的操作。我可能能够过滤出更大的记账条目池,只查看发票条目。但如果能把这些条目单独看作发票(而不是记账条目的一个子集),那就太方便了。

有没有什么建议可以帮助我实现这个目标?

2 个回答

0
  1. 父类中的所有字段在子类中也都有,所以不需要特别说明它们之间的关系。
  2. Django中的模型继承不好用,别用它。其实Python也不需要这个功能。
1

首先,从一个模型继承会在继承的模型中自动创建一个一对一的字段,指向父模型,所以你不需要自己添加这些字段。如果你真的想使用这种模型继承方式,可以把这些字段去掉。

如果你只是想共享模型中的某些成员,可以使用Meta继承,这样会在你继承的模型的表中创建相应的列。不过,这样会把你的JournalEntry分成两个表,但这样做可以更方便地只获取发票数据。

撰写回答