Рефакторинг бизнес-логики от представления к модели

У меня есть представление на django с небольшим количеством бизнес-логики в нем. Однако было бы полезно использовать эту информацию в других местах, поэтому мне кажется, что ее можно поместить в модель, но я не совсем уверен, как это сделать. В основном потому, что мне нужны конкретные данные пользователя. Вот что у меня есть на данный момент:

views.py

    def create_budget(self, context):
        starting_point = BudgetStartingPoint.objects.filter(owner=self.request.user)

        running_tally = starting_point[0].starting_amount

        budget_dict = {}
        for transaction in self.get_queryset():
            if transaction.income_type == "IN":
                running_tally += transaction.transaction_amount
            else:
                running_tally -= transaction.transaction_amount

            budget_dict[transaction] = [running_tally, transaction.income_type]

        context['budget'] = budget_dict

models.py

class BudgetTransaction(models.Model):
    """
    Individual transaction for Budget
    """

    transaction_types = [
        ('fixed', 'Fixed'),
        ('extra', 'Extra'),
    ]

    income_types = [
        ("IN", "Income"),
        ("OUT", "Expense"),
    ]

    frequencies = [
        ('weeks', 'Weekly'),
        ('fort', 'Fortnightly'),
        ('4week', 'Four Weeks'),
        ('months', 'Monthly'),
        ('years', 'Yearly'),
    ]

    today = datetime.today().date()

    id = HashidAutoField(
        primary_key=True, salt=f"transaction{settings.HASHID_FIELD_SALT}"
    )
    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        help_text="Owner of the item"
    )
    category = models.ForeignKey(BudgetCategory, on_delete=models.CASCADE, default=1, null=True)
    transaction_type = models.CharField(max_length=40, choices=transaction_types, default=1)
    transaction_name = models.CharField(max_length=100, null=False)
    transaction_amount = models.FloatField(null=False, default=100)
    income_type = models.CharField(max_length=20, choices=income_types, default="IN")
    next_date = models.DateField(null=False, default=today)
    frequency = models.CharField(max_length=20, choices=frequencies, default=1)
    complete = models.BooleanField(default=False)

    def __str__(self):
        return self.transaction_name

    class Meta:
        ordering = ['next_date']

Я чувствую, что у меня есть много вещей, которые было бы неплохо иметь в качестве метода модели, но они должны получить текущего пользователя, а я не уверен, как это сделать.

Не уверен, что это то, что вы имеете в виду, но вы можете сделать:

def create_budget(self, context):
    starting_point = BudgetStartingPoint.objects.filter(owner=self.request.user)

    running_tally = starting_point[0].starting_amount

    budget_dict = {}
    for transaction in self.get_queryset():
        running_tally = transaction.get_change(running_tally)
        budget_dict[transaction] = [running_tally, transaction.income_type]

    context['budget'] = budget_dict

class BudgetTransaction(models.Model):
    ....
    def get_change(self,value):
        return value + (
            self.transaction_amount 
            if self.income_type == "IN" else 
            -self.transaction_amount
        )
Вернуться на верх