django - 将子对象与Django中每个实例的父对象相关联?
问题描述
我有两个模型,一个Invoice
模型和一个Expense
模型。创建发票后,用户应该能够添加发票的所有费用。一旦创建了发票 - 这些费用应该以某种方式“检查”,因此新发票不会添加相同的费用。我需要对费用实例进行某种形式的检查,说“已开票”之类的。不完全确定如何仅使用..set.filter(...)
查询集我的两个模型如下所示:
费用模型
class Expense(Model):
cost = DecimalField(blank=True, null=True, max_digits=10, decimal_places=2)
project = ForeignKey(Project, on_delete=CASCADE)
user = ForeignKey(User, on_delete=CASCADE)
billable = BooleanField(default=False)
expense_date = DateField()
date_created = DateTimeField(auto_now_add=True)
invoice = ForeignKey("finances.Invoice", blank=True, null=True, on_delete=SET_NULL, help_text="Optionally link this to an existing invoice")
发票型号
class Invoice(Model):
issue_date = DateField(default=now)
due_date = DateField()
project = ForeignKey(Project, on_delete=CASCADE)
amount = DecimalField(blank=True, null=True, max_digits=100, decimal_places=2)
include_expenses = BooleanField(default=False, help_text='Check this box to include all expenses that are within the invoice billable date range')
billable_start = DateField(help_text="Logged hours start date")
billable_end = DateField(help_text="Logged hours end date")
我尝试在 Expense 模型上添加一个查询集,如下所示:
def get_billable_expenses(self):
"""Getting all expenses for selected billable period"""
start_week = self.get_start_isoweek()
end_week = self.get_end_isoweek()
return self.project.expense_set.filter(
expense_date__gte=self.billable_start,
expense_date__lte=self.billable_end,
billable=True,
invoice=self.id
)
然后添加一个在保存发票时触发的信号:
@receiver(post_save, sender=Invoice)
def prepare_calculation_data(sender, instance=None, created=False, **kwargs):
if created:
expenses_to_add = []
for expense in instance.get_billable_expenses():
expense.invoice = instance
expenses_to_add.append(expense)
Expense.objects.bulk_update(expenses_to_add, ['invoice'])
不知道如何处理这个问题 - 我想我会通过检查费用是否已经有与之相关的发票来解决它 - 如果没有 - 将其包含在新创建的发票中(如上get_billable_expenses()
所示),但这意味着不会有新的费用永远不会被添加,因为该invoice
字段不会为空
关于如何解决它的任何建议?
解决方案
我通过在我的Invoice
模型上使用两种方法来解决它。一种查询未开票的费用:
def get_billable_expenses(self):
"""Getting all expenses for selected billable period"""
start_week = self.get_start_isoweek()
end_week = self.get_end_isoweek()
return self.project.expense_set.filter(
expense_date__gte=self.billable_start,
expense_date__lte=self.billable_end,
status='approved',
billable=True,
invoice__isnull=True
)
然后在我的模板中显示这些费用:
def get_linked_expenses(self):
return self.project.expense_set.filter(
invoice=self.id
)
推荐阅读
- c++ - 如果函数声明匹配,是否有不需要占位符的 std::bind 替代方法?
- typescript - 如何测试某些东西是否是 Jasmine 给定类的数组?
- android - 如何查询 Android Room 的当前连胜和最长连胜
- wordpress - 如何在 WordPress Plugin Boilerplate 中正确实现 Bootstrap?https://wppb.me/
- linux - 使用 karate.fork() 执行多个 linux 命令
- python - 如何在 for 循环中进行网络抓取,而不会丢失 DOM?(Python,硒)
- html - 小屏幕的图像宽度未显示为 100%
- ssl - 如何使用 TLS 连接到 GRPC?
- node.js - 码头集装箱停了很长时间
- typescript - 如何正确覆盖打字稿中的方法?