0

我使用的是Django 1.10.7和Python 3.6.1。首先是我的代碼,然後是我的問題。基於Django模型字段計算的模板變量

我的模型看起來是這樣的:

class Thing(models.Model): 
    user = models.ForeignKey('auth.User') 
    title = models.CharField(max_length=200) 
    start_date = models.DateTimeField(
     default=timezone.now) 
    cost_per_day = models.DecimalField(max_digits=6, decimal_places=2) 

這裏是我的觀點:

def something_list(request): 
    things =Thing.objects.filter(start_date__lte=timezone.now()).order_by('start_date') 
    return render(request, 'myApp/something_list.html', {'things': things}) 

def thing_detail(request, pk): 
    thing = get_object_or_404(Thing, pk=pk) 
    return render(request, 'myApp/thing_detail.html', {'thing': thing}) 

我對這些視圖,在這裏我使用的模板標籤來顯示兩個變量模板塊。例如:

<h2 class="title"><a href="{% url 'thing_detail' pk=thing.pk %}">{{ thing.title }}</a></h2> 
<p>User: {{ thing.user }}</p> 
<div class="date"> 
    <p>Start Date: {{ thing.start_date }}</p> 
</div> 
<p>Cost per day: ${{ thing.cost_per_day }}</p> 

那麼這裏發生了什麼?

網絡用戶可以輸入我所說的任何數量的「事情」,包含4個字段:用戶,標題,開始日期和每日費用。我有兩個計算,我想做,並將其呈現在模板中。

問題1)用戶需要查看自從最初進入開始日期以來經過了多少天。計算將是當前時間/日期(現在)和開始日期的減法。我可以用這裏顯示的Django的timesince功能來做到這一點:

<button type="button" class="btn btn-info">{{ thing.quit_date|timesince }}</button> 

這使得有多少天,時間已經過去了 - 讓稱它爲「時間流逝」 - 完美。問題在於我的下一次計算。

問題2)我需要顯示'經過時間'(如上所示)乘以當前模型實例中的每日費用變量的計算。爲了清楚起見,我們假設開始日期是30.5天前,每天的成本是5.00美元。我需要乘以30.5乘以5.00美元。我很想簡單地乘以模板標籤,但我明白這不是它的工作原理。例如:

{{ thing.quit_date|timesince }} * {{ thing.cost_per_day }} 

有沒有辦法抓住這個timesince計算的結果... {{thing.quit_date | timesince}} ...作爲一個變量?我可能無法使用timesince功能進行此計算。

再一次,我最終需要做的是將「流逝的時間」乘以每天的費用,如下所示:(時間現在 - 開始日期)*(每日費用)。

我不知道該怎麼做models.pyviews.py。我正在尋找使用Django和Python 3.6來做到這一點的最佳做法。我是一個新手,我一整天都在搜索我的特定問題的答案。

預先感謝,請讓我知道如果我需要提供更多的信息!

UPDATE
這裏是根據建議,我更新的模式,雖然不工作(在timesince財產的工作需要):

from django.db import models 
from django.utils import timezone 
from datetime import datetime 

class Thing(models.Model): 
quitter = models.ForeignKey('auth.User') 
title = models.CharField(max_length=200) 
quit_date = models.DateTimeField(default=timezone.now) 
cost_per_day = models.DecimalField(max_digits=6, decimal_places=2) 
notes = models.TextField() 

@property 
def timesince(self): 
    "Time since quit date" 
    now = datetime.now() 
    then = self.quit_date 
    return (now - then) 

@property 
def savings(self): 
    "Savings since quitting" 
    return self.timesince * self.cost_per_day 

這是我更新的模板:

<h4>Here are some calculations for this information...</h4> 
    <p>Days since you quit:</p> 
    <button type="button" class="btn btn-info">{{ thing.timesince }}</button> 
    <hr> 
    <p>How much money you have saved:</p> 
    <button type="button" class="btn btn-info">{{ thing.savings }}</button> 

我肯定的問題在於減去日期。任何對此的洞察都將非常有幫助。模板變量{{}}正在工作,但模型中缺少一塊。順便說一下,當我將「天」連接到任何日期時間變量時,它會在我的錯誤中說明錯誤,並告訴我錯誤。也許有使用DateTimeField和datetime.now()實例的問題?

+0

您是否考慮過自定義模板標記? https://docs.djangoproject.com/en/1.11/howto/custom-template-tags/ –

+0

不可否認,在我的學習中,我現在有點被自定義模板標籤嚇倒了。我感謝你的建議!我將按照以下建議嘗試@property。 –

回答

1

我會建議在模型本身上創建一個屬性來計算這個。從當前日期減去退出日期會給你一個timedelta對象。從那裏我們可以得到的日子,並把它的成本。

from django.utils import timezone 

class Thing(models.Model): 
    ... 

    @property 
    def cost(self): 
     days = (timezone.now().date() - self.quit_date).days 
     return days * self.cost_per_day 

然後你的模板變得非常簡單。

{{ thing.cost }} 
+0

你好,非常感謝。我想這很明顯,我正在做一個「退出這個」應用程序。我會試試這個! –

1

這真的不是模板標籤的用途。他們的目的是顯示變量,並稱之爲一天,用一些小的功能實用程序。

對於你的方程,最好的做法是在模型中實現它們。

from datetime import datetime 

class Thing(models.Model): 
    quit_date = models.DateTimeField() 
    cost_per_day = models.FloatField() ??? 

    @property 
    def timesince(self): 
     # Time since last whatever 
     elapsed = datetime.now() - self.quit_date 
     return elapsed.days 

    @property 
    def calculate_cost(self): 
     return self.timesince * self.cost_per_day 

然後,你可以顯示每個使用{{ thing.timesince }}和模板{{ thing.calculate_cost }}值的。

+0

非常感謝。我會試試這個! –

+0

@Brobin我在減法日期時遇到了麻煩。我試過了你的代碼示例和其他一些變體。你的代碼不會產生錯誤,但它什麼也不顯示。如果我現在返回,它現在顯示時間和日期。如果我顯示「然後」,則顯示退出日期。所以我知道變量在模板中工作。如果我回到「現在 - 然後」(減法),那就什麼都沒有。我應該使用當前的代碼更新我的帖子嗎? –

0

這是一個有效的答案。我認爲問題在於我使用「datetime.now()」而不是「timezone.now()」。這可能不是在Django/Python中處理這個問題的最佳方法。我很感謝關於如何使其成爲「最佳實踐」的評論。我真的很感謝這個幫助!

@property 
def timesince(self): 
    "Time since quit date" 
    now = timezone.now() 
    then = self.quit_date 
    return (now - then).days 

@property 
def savings(self): 
    "Savings since quitting" 
    return self.timesince * self.cost_per_day