Django queryset для отображения значений каждый месяц

Я делаю Django APP (требуется) для подсчета прибыли и убытков каждый месяц.

Есть функция, которую я хотел ввести, что через N месяцев вы будете платить стоимость/N (т.е. $100/5, что равно $20 в месяц).

Эта функция была бы похожа на банковскую APP, показывающую, сколько вам еще предстоит заплатить (например: с этого месяца по октябрь)

Кстати, из проигрышей есть только одна запись (я стараюсь не менять это)

Пока все хорошо, но записи появляются только в месяце моего поиска (см. ниже), а когда я пытаюсь использовать:

Account.objects.filter(date__year__gte=y) or Account.objects.filter(date__month__gte=m)

или

Account.objects.filter(date__year__lt=y) or Account.objects.filter(date__month__lt=m)

В записи отображается весь год или месяцы, которые больше или меньше сохраненного месяца (без фильтра, так что если это с июля по ноябрь, то будет показано до декабря или в январе)

View.py

def account(request, pk):
search = f"{datetime.now().year} - {datetime.now().month:02}"
account = Account.objects.get(id=pk)
ctx = {
    'search': search
}
if request.GET.get('month'):
    search = request.GET.get('month')
    y, m = search.split('-')
    ctx.update({
        'search': search
    })
    date_loss = filter_by_model_date(Loss, m, y)
    date_profit = filter_by_model_date(Profit, m, y)
    profit = filter_by_account(date_profit, account)  
    loss = filter_by_account(date_loss, account)  
    ctx.update({
         'profit': profit, 'loss': loss
    })
return render(request, 'account/account.html', ctx)

Functions.py

def filter_by_model_date(model, month, year):
    """
    Filter by Model by month and year
    """
    return model.objects.filter(date__month=month, date__year=year)

def filter_by_account(model, field):
    """
    Logs Filter by account
    """
    return model.filter(account=field)

Models.py

class Account(models.Model):
    name = models.CharField(max_length=200)

class Profit(models.Model):
    [...]
    value = models.FloatField()
    date = models.DateField(default=datetime.today)
    account = models.ForeignKey(Account, on_delete=models.CASCADE)

class Loss(models.Model):
    [...]
    months = models.IntegerField()
    value = models.FloatField()
    date = models.DateField(default=datetime.today)
    account = models.ForeignKey(Account, on_delete=models.CASCADE)

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

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

Так что мне удалось сделать это с помощью списка... Это не сложно (я не знаю, является ли это питоническим), но я сделал это таким образом, и это работает !

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

Я просто хочу сказать одну вещь: "Удачи и никогда не сдавайся!"

View.py

def account(request, pk):
search = f"{datetime.now().year} - {datetime.now().month:02}"
account = Account.objects.get(id=pk)
ctx = {
    'search': search
}
if request.GET.get('month'):
    search = request.GET.get('month')
    y, m = search.split('-')
    ctx.update({
        'search': search
    })
    date_loss = filter_by_model_date(Loss, m, y)
    date_profit = filter_by_model_date(Profit, m, y)
    profit = filter_by_account(date_profit, account)  
    loss = filter_by_account(date_loss, account)  
    ctx.update({
         'profit': profit, 'loss': loss
    })

    list_month = check_is_month(Loss, account, y, m) # Added this line of code

        data.update({
            'month': list_month
        })

return render(request, 'account/account.html', ctx)

Functions.py

def check_is_month(model, field, year, month):
    """
    Return a list with all the losses 
    """
    buy_loss = filter_by_model_account(model, field)
    list_loss = []
    for b in buy_loss: #Run through the filter
        if get_date_iso_format(year, month) >= b.date: #If the b.date is lesser or equal the search, this if not to show in earlier months (P.S: Had to transform in isoformat)
            list_loss.append(b) #Append the record
            final_date = check_final_date(b.date, c.months) #Get Final Date
            m = (int(month) - b.date.month) #Get The number of months (Just for show)
            if final_date > replace_month_year(get_date_iso_format(year, month), month, year): # If Final date is greater than the month searched (P.S: Had to transform in isoformat)
                if m > 0: #Another just for show
                    b.months = f"{m}/{b.months}"
                else:
                    b.months = f"{m + 12}/{b.months}"
                b.date = replace_month_year(b.date, month, year) #Change the date like a Bank APP
            elif final_date < replace_month_year(get_date_iso_format(year, month), month, year): #If the date is less 
                list_loss.remove(b)
    return list_loss


def get_date_iso_format(year, month):
    """
    Return String date year/month/01
    """
    return datetime.fromisoformat(f"{year}-{month}-01").date()

def replace_month_year(date, month, year):
    """
    Replace function
    """
    return date.replace(month=int(month), year=int(year))


def check_final_date(date, months):
    """
    Return final date
    """
    return date + timedelta(seconds=months* 30 * 24 * 60 * 60)

def filter_by_model_account(model, field):
    """
    Filter by Model and Account
    """
    return model.objects.filter(account=field)

В шаблоне вы можете пробежаться по убыткам, прибылям и месяцам, будьте добры делать все, что вам заблагорассудится!

Вернуться на верх