计算同一模型中字段不同行中连续数字之间的差异
calculate difference between consecutive numbers in different rows of a field in the same model
我正在尝试计算模型 odometer_reading 字段中连续数值之间的差异。
我的 Models.py 有如下字段:
class Refuel(models.Model):
vehicle = models.ForeignKey(Vehicle, blank=True, null=True, on_delete=models.SET_NULL)
gaz_station = models.ForeignKey(
GazStation, related_name=_("Station"), blank=True, null=True, on_delete=models.SET_NULL
)
odometer_reading = models.PositiveIntegerField(_("Compteur KM"), blank=True, null=True)
snitch = models.PositiveIntegerField(_("Mouchard KM"), blank=True, null=True)
fuel_quantity = models.DecimalField(_("Quantitée en Litres"), max_digits=5, decimal_places=1)
fuel_unit_price = models.DecimalField(_("Prix en DH"), max_digits=6, decimal_places=2)
note = models.CharField(_("Remarque"), max_length=255, blank=True, null=True)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True, editable=False)
updated_at = models.DateTimeField(_("Updated at"), auto_now=True)
is_active = models.BooleanField(default=True)
@property
def total_price(self):
total_price = self.fuel_quantity * self.fuel_unit_price
return total_price
class Meta:
ordering = ["gaz_station", "-created_at"]
def __str__(self):
return self.vehicle.serie
我想使用 CBV 来获取同一车辆每两次加油之间的距离,以便计算每公里的油耗。
有办法吗?
已编辑:
我想return每次加油时使用先例加油的每公里油耗。
在您的视图中,您可以创建一个拉取两个加油对象的视图函数,然后您可以获取差异并将其用作模板上下文。然后,您可以在模板中使用您所称的任何名称来访问它,在此示例中,我们只是使用了与变量“difference”相同的名称。
from myapp.models import Refuel
from django.template import loader
from django.shortcuts import render
from django.http import HttpResponse
def odometer_difference(request):
# get the two refuel objects with the odometer readings you needed to compare
refuel_1 = Refuel.objects.filter('your_filter')
refuel_2 = Refuel.objects.filter('your_filter')
#define template
template = loader.get_template('my_template.html')
difference = refuel_2.odometer_reading - refuel_1.odometer_reading
context = { 'difference':difference}
return HttpResponse(template.render(context, request))
您可以使用 Window
functions that uses Lag
获取前一行的值,如下所示:
from django.db.models import Window
from django.db.models.functions import Lag
last_odometer_reading = Window(
expression=Lag('odometer_reading', default=0),
partition_by=F('vehicle')
order_by=F('created_at').asc(),
)
Refuel.objects.annotate(
last_odometer_reading=last_odometer_reading
).annotate(
odometer_difference=F('odometer_reading') - F('last_odometer_reading')
)
每个加油行都会标注上次的里程表读数(基于同一车辆的加油情况),同时还会标注当前读数与上次读数的差值。
我在验证新记录时使用 form_valid **RefuelCreatView**
来获取最旧的数据并执行我的计算并存储 RefuelConsumption 模型。
class RefuelCreationView(LoginRequiredMixin, CreateView):
model = Refuel
form_class = RefuelCreationForm
template_name = "refuel/refuel_form.html"
success_url = reverse_lazy("refuel:controlor-refuel-list")
def form_valid(self, form):
form.instance.user_id = self.request.user.id
form.instance.gaz_station = GazStation.objects.get(Controlor_id=self.request.user.id)
old_refuel_data = Refuel.objects.order_by().distinct("vehicle")
for refuel in old_refuel_data:
if refuel.vehicle == form.instance.vehicle and form.instance.odometer_reading:
consumption = (refuel.fuel_quantity / (form.instance.odometer_reading - refuel.odometer_reading)) * 100
FuelConsumption.objects.create(
vehicle=refuel.vehicle,
gaz_station=form.instance.gaz_station,
Controlor_id=self.request.user,
driver=refuel.vehicle.driver,
consumption=consumption,
is_active=True,
)
elif refuel.vehicle == form.instance.vehicle and form.instance.snitch:
consumption = (refuel.fuel_quantity / (form.instance.snitch - refuel.snitch)) * 100
FuelConsumption.objects.create(
vehicle=refuel.vehicle,
gaz_station=form.instance.gaz_station,
Controlor_id=self.request.user,
driver=refuel.vehicle.driver,
consumption=consumption,
is_active=True,
)
return super().form_valid(form)
def get_queryset(self, *args, **kwargs):
return Refuel.objects.select_related("vehicle__gaz_station__Controlor_id").filter(
vehicle__gaz_station__Controlor_id=self.request.user
)
这很好用。我不知道它是否尊重编程的最佳实践,我愿意接受任何建议。
我正在尝试计算模型 odometer_reading 字段中连续数值之间的差异。
我的 Models.py 有如下字段:
class Refuel(models.Model):
vehicle = models.ForeignKey(Vehicle, blank=True, null=True, on_delete=models.SET_NULL)
gaz_station = models.ForeignKey(
GazStation, related_name=_("Station"), blank=True, null=True, on_delete=models.SET_NULL
)
odometer_reading = models.PositiveIntegerField(_("Compteur KM"), blank=True, null=True)
snitch = models.PositiveIntegerField(_("Mouchard KM"), blank=True, null=True)
fuel_quantity = models.DecimalField(_("Quantitée en Litres"), max_digits=5, decimal_places=1)
fuel_unit_price = models.DecimalField(_("Prix en DH"), max_digits=6, decimal_places=2)
note = models.CharField(_("Remarque"), max_length=255, blank=True, null=True)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True, editable=False)
updated_at = models.DateTimeField(_("Updated at"), auto_now=True)
is_active = models.BooleanField(default=True)
@property
def total_price(self):
total_price = self.fuel_quantity * self.fuel_unit_price
return total_price
class Meta:
ordering = ["gaz_station", "-created_at"]
def __str__(self):
return self.vehicle.serie
我想使用 CBV 来获取同一车辆每两次加油之间的距离,以便计算每公里的油耗。
有办法吗?
已编辑:
我想return每次加油时使用先例加油的每公里油耗。
在您的视图中,您可以创建一个拉取两个加油对象的视图函数,然后您可以获取差异并将其用作模板上下文。然后,您可以在模板中使用您所称的任何名称来访问它,在此示例中,我们只是使用了与变量“difference”相同的名称。
from myapp.models import Refuel
from django.template import loader
from django.shortcuts import render
from django.http import HttpResponse
def odometer_difference(request):
# get the two refuel objects with the odometer readings you needed to compare
refuel_1 = Refuel.objects.filter('your_filter')
refuel_2 = Refuel.objects.filter('your_filter')
#define template
template = loader.get_template('my_template.html')
difference = refuel_2.odometer_reading - refuel_1.odometer_reading
context = { 'difference':difference}
return HttpResponse(template.render(context, request))
您可以使用 Window
functions that uses Lag
获取前一行的值,如下所示:
from django.db.models import Window
from django.db.models.functions import Lag
last_odometer_reading = Window(
expression=Lag('odometer_reading', default=0),
partition_by=F('vehicle')
order_by=F('created_at').asc(),
)
Refuel.objects.annotate(
last_odometer_reading=last_odometer_reading
).annotate(
odometer_difference=F('odometer_reading') - F('last_odometer_reading')
)
每个加油行都会标注上次的里程表读数(基于同一车辆的加油情况),同时还会标注当前读数与上次读数的差值。
我在验证新记录时使用 form_valid **RefuelCreatView**
来获取最旧的数据并执行我的计算并存储 RefuelConsumption 模型。
class RefuelCreationView(LoginRequiredMixin, CreateView):
model = Refuel
form_class = RefuelCreationForm
template_name = "refuel/refuel_form.html"
success_url = reverse_lazy("refuel:controlor-refuel-list")
def form_valid(self, form):
form.instance.user_id = self.request.user.id
form.instance.gaz_station = GazStation.objects.get(Controlor_id=self.request.user.id)
old_refuel_data = Refuel.objects.order_by().distinct("vehicle")
for refuel in old_refuel_data:
if refuel.vehicle == form.instance.vehicle and form.instance.odometer_reading:
consumption = (refuel.fuel_quantity / (form.instance.odometer_reading - refuel.odometer_reading)) * 100
FuelConsumption.objects.create(
vehicle=refuel.vehicle,
gaz_station=form.instance.gaz_station,
Controlor_id=self.request.user,
driver=refuel.vehicle.driver,
consumption=consumption,
is_active=True,
)
elif refuel.vehicle == form.instance.vehicle and form.instance.snitch:
consumption = (refuel.fuel_quantity / (form.instance.snitch - refuel.snitch)) * 100
FuelConsumption.objects.create(
vehicle=refuel.vehicle,
gaz_station=form.instance.gaz_station,
Controlor_id=self.request.user,
driver=refuel.vehicle.driver,
consumption=consumption,
is_active=True,
)
return super().form_valid(form)
def get_queryset(self, *args, **kwargs):
return Refuel.objects.select_related("vehicle__gaz_station__Controlor_id").filter(
vehicle__gaz_station__Controlor_id=self.request.user
)
这很好用。我不知道它是否尊重编程的最佳实践,我愿意接受任何建议。