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)
В шаблоне вы можете пробежаться по убыткам, прибылям и месяцам, будьте добры делать все, что вам заблагорассудится!