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