模板变量基于使用Django Model

时间:2017-06-06 19:32:19

标签: django python-3.x django-models django-templates django-views

我正在使用Django 1.10.7和Python 3.6.1。先是我的代码,然后是我的问题。

我的模型看起来像这样:

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>

那么这里发生了什么?

网络用户可以输入我正在呼叫的任何数量的&#34; Things&#34;包含4个字段:用户,标题,开始日期和每日费用。我有两个我想做的计算,并在模板中渲染它们。

问题1 )用户需要查看自最初进入开始日期以来经过了多少天。计算将是当前时间/日期(现在)和开始日期的减法。我能够通过使用此处显示的Django timesince 功能实现此目的:

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

这会渲染已经过了多少天和几小时 - 让我们称之为“时间已过去”#39; - 完美。问题在于我的下一次计算。

问题2 )我需要显示已经过去的时间&#39; (如上所示)乘以当前Model实例中的每日成本变量。为了清楚起见,我们假设开始日期是30.5天前,每天的费用是5.00美元。我需要将30.5乘以$ 5.00。我希望简单地将模板标签相乘,但我知道它不是如何工作的。例如:

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

有没有办法从计算中捕获这个时间的结果...... {{thing.quit_date | timesince}} ...作为变量?我可能无法使用timesince功能进行此计算。

再次,我最终需要做的是将&#34;时间过去&#34;每天的费用,如下所示:(现在时间 - 开始日期)*(每日费用)。

我不知道如何在 models.py views.py 中执行此操作。我正在寻找使用Django和Python 3.6来实现这一目标的最佳实践方法。我是一个新手,我整天都在搜索我的特定问题。

提前致谢,如果我需要提供更多信息,请告诉我们!

更新
这是我基于建议的更新模型,虽然不起作用(属性需要工作的时间):

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>

我确定问题在于减去日期。任何洞察力都会非常有帮助。模板变量{{}}正在运行,但模型中缺少一个部分。

顺便说一下,当我连接&#34;天&#34;对于任何日期时间变量,它给我发错误说.days它给了我错误。使用DateTimeField和datetime.now()实例时可能存在问题?

3 个答案:

答案 0 :(得分: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 }}

答案 1 :(得分: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 }}显示每个值。

答案 2 :(得分: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