Django проверка значений для вычисления
Hej!
Мне нужно сделать несколько простых вычислений отфильтрованных данных в моем представлении django. Это прекрасно работает, когда значения в выбранном фильтре. Если значение равно 0 или None, я получаю ошибку сервера и сайт падает. Поэтому мне нужен валидатор, чтобы убедиться, что заданное значение не 0 и не None.
(моя попытка внизу) В настоящее время, если валидатор добавлен, он дает мне сообщение, что объект 'float' не является вызываемым, даже до того, как я дойду до опции/шаблона фильтра.
А также: в моей модели есть m2m к модели, откуда я беру значения. Для каждого значения может быть выбрана единица измерения, и я хочу вычислить только если единицы измерения идентичны, иначе я хочу получить предупреждение.
Кто-нибудь знает, как этого добиться? Или где искать?
Любая помощь будет принята с благодарностью! :)
# validators.py
def validate_values(value):
if value == 0:
raise ValidationError(_('One of the given values is 0 or empty and the calculation therefore cannot be proceeded.'),
code='notinrange')
# views.py
def process_mass_intensity(request):
plants = Plant.objects.all()
myFilter = PlantsNameFilter(request.GET, queryset=plants)
plants = myFilter.qs
total_m = plants.aggregate(Sum('used_in_plant__value'))['used_in_plant__value__sum']
product_m = plants.aggregate(product_mass=Sum('used_in_plant__value',
filter=Q(used_in_plant__input_or_output='OUT')))['product_mass'](validators=[validate_values])
pmi = (total_m / product_m)(validators=[validate_values])
context = {"plants": plants, "myFilter": myFilter, "total_m": total_m, "product_m": product_m, "pmi": pmi}
return render(request, 'kpi/process_mass_intensity.html', context)
# models.py
class Plant(models.Model):
name = models.CharField(
max_length=200
)
used_xducts = models.ManyToManyField(
Xduct,
through="UsedXduct",
blank=True,
related_name="used_in_plant"
)
class UsedXduct(models.Model):
plant = models.ForeignKey(
Plant,
on_delete=models.PROTECT,
related_name="used_in_plant"
)
xduct = models.ForeignKey(
Xduct,
on_delete=models.PROTECT,
related_name="xduct"
)
value = models.FloatField()
quantity = models.ForeignKey(
Quantity,
on_delete=models.PROTECT
)
unit = models.ForeignKey(
Unit,
on_delete=models.PROTECT
)
Валидаторы применяются на уровне поля. Здесь также можно использовать MinValueValidator вместо пользовательской функции валидатора. Давайте разложим это по полочкам.
Причина, по которой вы получаете эту ошибку, заключается в том, что вы умножаете значение (точнее, float) на (validators=[validate_values])
, которое является функцией. Это не имеет смысла.
Вместо этого, вы хотите поместить валидаторы внутри объявления поля в вашей модели. Таким образом:
from django.core.validators import MinValueValidator
class UsedXduct(models.Model):
plant = models.ForeignKey(
Plant,
on_delete=models.PROTECT,
related_name="used_in_plant"
)
xduct = models.ForeignKey(
Xduct,
on_delete=models.PROTECT,
related_name="xduct",
validators=[MinValueValidator(0)]
)
value = models.FloatField()
quantity = models.ForeignKey(
Quantity,
on_delete=models.PROTECT,
validators=[MinValueValidator(0)]
)
unit = models.ForeignKey(
Unit,
on_delete=models.PROTECT
)
В качестве альтернативы, чтобы не выполнять валидатор при создании модели, вы можете просто запустить функцию валидатора в самом представлении:
def process_mass_intensity(request):
plants = Plant.objects.all()
myFilter = PlantsNameFilter(request.GET, queryset=plants)
plants = myFilter.qs
total_m = plants.aggregate(Sum('used_in_plant__value'))['used_in_plant__value__sum']
product_m = validate_values(plants.aggregate(product_mass=Sum('used_in_plant__value', filter=Q(used_in_plant__input_or_output='OUT')))['product_mass'])
pmi = validate_values(total_m / product_m)
context = {"plants": plants, "myFilter": myFilter, "total_m": total_m, "product_m": product_m, "pmi": pmi}
return render(request, 'kpi/process_mass_intensity.html', context)
Надеюсь, это поможет, дайте мне знать, если у вас есть вопросы.