基本上我正在为我国的公用事业公司创建一个关税计算器,基于累进费率表,下面给出一个例子
2.(a)在任何一个月内,少于1,001加仑的费用........................... .. ... $ 9.23
(b)此后每加仑加仑的比例费用高达2,000加仑,按每1000加仑的比率计算.................. .. $ 15.89
(c)每加仑2,000加仑以及每加仑加仑3000加仑的每加仑的比例费用,按每1000加仑的比率计算。......... .. $ 17.43
(d)每加仑3000加仑以上加仑加4,000加仑的比例费用,按每1000加仑计算。......... .. $ 18.45
(e)每加仑4,000加仑以及每加仑加仑5,000加仑的每加仑的比例费用....... .. $ 19.48
(f)每加仑5,000加仑以及每加仑6,000加仑每加仑的比例费用,按每1000加仑计算。......... .. $ 20.50
(p)每加仑高于6,000加仑和高达7,000加仑的每加仑的比例费用,按每1000加仑的比率计算。......... .. $ 21.01(h)每加仑7,000加仑以及每加仑加仑8,000加仑的每加仑的比例费用,每1000加仑的比率........... $ 21.53
(i)每加仑8,000以上加仑的比例费用,每1000加仑... $ 22.04
我正在考虑使用以下字段来执行Rate模型:
我的观点会接受来自加仑数量,供应区域的表格的帖子,并应回复从费率表中计算的使用量。
我会在视图中做这样的事情
from models import Rate
def tarrif_calc(request,gallons,area):
rate = Rate.objects.get(area_of_supply=area, from_gallons >= gallons, to_gallons <= gallons)
rate_per_gal = rate.rate_per_1000g/1000
usage = gallons * rate_per_gal
return usage
这是我能想到的最简单的事情,但是我不确定如何处理渐进率?任何想法?我是在正确的轨道上吗?
答案 0 :(得分:1)
业务规则应以代码表示。 More info
在仔细阅读你的问题之后,看起来你可能有许多这样的表需要查询。将许多类似的此类结构合法地放入数据库中。现在我假设你有。如果你真的只有一个表,那么案例分析可能是最简洁的。
在我自己的django应用程序中,我发现将业务逻辑放在一个非常自然的地方。模型看起来很明显,但很少能够获得必要的上下文,以便做出明智的决定。
通常我会把它分成几个依赖的应用程序。一个应用程序提供非常高级,抽象的模型和表单。另一个应用程序使用业务规则扩展了第一个表单。
第一个问题是查询Rate模型。这段代码实际上并不起作用。你不能在python中传递惰性比较。 Django has a mechanism for that,通过修改参数名称。
rate = Rate.objects.get(area_of_supply=area, from_gallons__gte=gallons, to_gallons__lte=gallons)
我不确定你的数据库是什么样的,但要确保有一个关于from_gallons和to_gallons的索引,否则这个查询会非常慢。
你的例子听起来并没有真正改变国家。如果这是真的,那么你可能应该使用GET视图而不是POST。
在任何一种情况下,逻辑的第一部分都是相同的。接收请求并验证表单输入。
# in "myproject/businessrules/forms.py"
from django import forms
from myproject.otherapp.models import Area
class RateForm(forms.Form):
# declare as instance variables the data actually posted
quantity = forms.DecimalField(label="amount of gallons")
area = forms.ModelChoiceField(label="area of supply", queryset=Area.objects.all() )
# now add the business rule!
def clean(self):
cleaned_data = self.cleaned_data # quantity and area area already validated
rate = Rate.objects.get(
area_of_supply=cleaned_data["area"],
from_gallons__gte=cleaned_data["gallons"],
to_gallons__lte=cleaned_data["gallons"])
usage = cleaned_data["gallons"] * rate.rate_per_1000g/1000
cleaned_data["usage"] = usage
return cleaned_data
现在所需要的只是实际使用它。
# in "myproject/myapp/views.py"
from django.shortcuts import render_to_response
from businessrules import RateForm
def tarrif_view(request):
form = RateForm(request.GET)
if form.is_valid():
context = { "form": form, "valid": True, "usage":form.cleaned_data["usage"] }
else:
context = { "form": form, "valid": False }
return render_to_response("tarrif.html", context)
视图中嵌入了很少的业务知识。只有表格的事实 将清理后的计算结果存储在其“使用”键中。但由于这种观点恰恰是为了获得这种价值,所以这是正确的做法。
还需要使用表单的模板。 (我的django模板技能只是马马虎虎。如我所说,我更喜欢jinja2,所以你应该这样做)
就个人而言,我不太喜欢将单个表单结果移动到模板上下文中,我只是使用整个处理过的表单。我在jinja2中编写自己的模板,所以如果你的模板设计师不值得信任,你可能想要比这更谨慎地制作你的上下文。
{# in "myproject/templates/tarrif.html" #}
{% if valid %}
Usage: {{ usage }} dollars.
{% else %}
<form action="" method="GET">
{{ form }}
<input type="submit" \>
</form>
{% endif %}
同样,模板中不会出现比视图中更多的业务逻辑。
答案 1 :(得分:0)
现在来自@TokenMacGuy的一个非常完整的例子。我明白了你对表单中业务逻辑的意思。虽然我认为你没有说明累积费率,这将使它更长。
我在完成问题之后回答了我自己的问题,并希望其他人可以输入并启发django用户关于业务逻辑案例。
所以我做了什么:
首先创建一个费率模型,以便将其存储在数据库中。我用速率级别标记每个费率,以便能够处理累进评级。
class Rate(models.Model):
area_of_supply = models.ForeignKey(SupplyArea)
description = models.TextField()
rate_level = models.CharField(max_length=2,choices=RATE_LEVEL_CHOICES,)
rate_per_1k_gallons = models.DecimalField(max_digits=10,decimal_places=2)
然后我在我的views.py中创建了将处理来自表单的请求的视图(在我的例子中是ajax和常规形式)。和“业务逻辑”一样,在我的例子中是“traffic_calc()”
def tariff(request):
if request.method == 'POST':
form = TariffForm(request.POST)
if form.is_valid():
gallons = form.cleaned_data['gallons']
gallons = int(gallons)
area_id = form.cleaned_data['tariff']
area = area_id.name
usage = tarrif_calc(request, area_id, gallons)
response_dict = {'gallons': gallons,'area': area,'usage': usage}
if request.is_ajax():
return HttpResponse(simplejson.dumps(response_dict), mimetype='application/json')
return render_to_response('rates/tariff_form.html', response_dict)
else:
form = TariffForm()
return render_to_response('rates/tariff_form.html', {'form': form})
def tarrif_calc(request, area, gallons):
r_levels = gallons//1000
remainder = gallons%1000
usage = 0
i = 1
if r_levels < 1:
rate = Rate.objects.get(area_of_supply=area,rate_level=1)
usage = rate.rate_per_1k_gallons
else:
if r_levels >= 8:
while i <= 9:
rate = Rate.objects.get(area_of_supply=area,rate_level=i)
usage += rate.rate_per_1k_gallons
i += 1
if gallons > 9000:
remainder = gallons - 9000
remainder_rate = Rate.objects.get(area_of_supply=area,rate_level=9)
usage += remainder * remainder_rate.rate_per_1k_gallons/1000
usage = round(usage,2)
else:
while i <= r_levels:
rate = Rate.objects.get(area_of_supply=area,rate_level=i)
usage += rate.rate_per_1k_gallons
i += 1
remainder_level = r_levels+1
if remainder_level >= 9:
remainder_rate = Rate.objects.get(area_of_supply=area,rate_level=9)
else:
remainder_rate = Rate.objects.get(area_of_supply=area, rate_level=remainder_level)
usage += remainder * remainder_rate.rate_per_1k_gallons/1000
usage = round(usage,2)
return usage
我同意@TokenMacGuy ..我本应该使用GET,但我使用POST我猜是因为如果js不可用,常规表单也可以。我同意在这个级别@TokenMacGuy可能只是从视图导入tariff_calc并在他的forms.py中使用它。
然后我创建了必要的表单和模板以及处理ajax发布的javascript(虽然没有必要)
// JavaScript Document
$(document).ready(function() {
$('#tariff_form').submit(function(event){
event.preventDefault(); // stop the form from submitting and refreshing the page
var form = this; // in jQuery, this refers to the current element, which is #article_form
// grab each form value
var data = {};
gallons = $('#id_gallons').val();
tariff = $('#id_tariff').val();
// now send the data to the server via AJAX
if(gallons && tariff)
{
$.ajax({
type: "POST",
url: "/tariff-calculator/",
data: "gallons="+gallons+"&tariff="+tariff,
dataType: "json",
success: function(json){
$('#gallons_cont').html(json['gallons']);
$('#area_cont').html(json['area']);
$('#usage_cont').html(json['usage'])
$('#results_json').show('slow');
},
});
}
else
{
alert('Please Fill All Fields')
}
});
});
我猜这两种方法都很相似并且都有效(虽然我没有试过@ TokenMacGuy),除了tariff_calc()函数外,似乎MackGuy解决了这个问题所以我会给他正确的答案,尽管我我会喜欢在forms.py中更多关于业务逻辑的反馈,因为我并不完全相信,或者认为存在巨大差异。