Связать дочерний объект с родительским объектом для каждого экземпляра в Django? - PullRequest
0 голосов
/ 05 августа 2020

У меня две модели: модель 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")

Я пробовал добавление набора запросов к модели расходов как таковой:

    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 не будет пустым

Есть предложения, как решить эту проблему?

1 Ответ

0 голосов
/ 06 августа 2020

Я решил это с помощью двух методов на моей модели 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
        )
...