Я знаю, что эта тема упоминалась несколько раз, но я не могу найти решение своей проблемы. Поэтому примите мои извинения за повторный запрос.
У меня есть фильтр на основе условий, который мне не подходит.
вот мой файл models.py:
class Itemslist(models.Model):
safety_stock = models.DecimalField(blank=True, null=True, max_digits=19, decimal_places=0)
current_stock = models.DecimalField(max_digits=19, decimal_places=0)
def above_below_ss(self):
ab = Decimal(self.current_stock-self.safety_stock)
return round(ab,0)
def __str__(self):
return self.item_n
Извините, нужно исправить отступ, так как все это относится к одному классу модели.
и вот что у меня есть в файле views.py:
from .models import *
def toorder(request):
# toorder=Itemslist.objects.all
sorted=Itemslist.objects.annotate(dontshow=above_below_ss()).exclude(dontshow__gt=0)
context={ 'sorted': sorted }
return render(request, 'toorder.html', context)
Так вот проблема: когда я использую
toorder=Itemslist.objects.all
все работает, но когда я пытаюсь это сделать:
sorted=Itemslist.objects.annotate(dontshow=above_below_ss()).exclude(dontshow__gt=0)
не работает.
Интересно Дело в том, что раньше он работал, но мой код не работал без копии (во время резервного копирования, что довольно забавно),
И теперь это не работает.
Я получаю это сообщение:
NameError at /toorder
name 'above_below_ss' is not defined
Request Method: GET
Request URL: http://localhost:8000/toorder
Django Version: 2.2.5
Exception Type: NameError
Exception Value:
name 'above_below_ss' is not defined
Exception Location: /Users/artursjermolickis/projects/osmiocenter/mysite/itemlist/views.py in toorder, line 220
Python Executable: /Users/artursjermolickis/projects/osmiocenter/venv/bin/python3
Python Version: 3.7.4
Python Path:
['/Users/artursjermolickis/projects/osmiocenter/mysite',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python37.zip',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/lib-dynload',
'/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf',
'/Users/artursjermolickis/projects/osmiocenter/venv/lib/python3.7/site-packages/odf']
Если вам нужно больше кусков кода от меня, пожалуйста, просто скажите мне, что вам нужно.
Действительно надеюсь, что Вы можете помочь мне здесь.
Вот дополнительные комментарии к моему вопросу.
Необходимо отфильтровать результат по математической функции.
в качестве примера, который я разместил safety_stock
, и предоставленное решение работает для этого.
Но, как вы уже упоминали, мне нужна сортировка базы данных по более сложной функции, поэтому лучше делать это в моделях. py вместо того, чтобы делать это в vews.py, чтобы я мог использовать его позже. Итак, код, который я хочу заменить safety_stock
следующим:
def safe_stock(self):
if self.safety_stock ==0:
ss= (self.sales6mavgs()+self.stdev())*(self.lead_time+self.bookingterms)
else:
ss=Decimal(self.safety_stock)
return Decimal(ss.quantize(Decimal('1'),rounding=ROUND_UP))
Итак, из ваших предложений я понял, что мне нужно реализовать ExpressionWrapper
.
Как реализовать его с помощью ExpressionWrapper
Теперь на вопрос дан ответ, подробности см. ниже Я добавил менеджера в мои models.py:
class ToOrderManager(models.Manager):
def get_queryset(self):
return super(ToOrderManager, self).get_queryset().annotate(
dontshow=Round(ExpressionWrapper((F('current_stock')-F('safety_stock')), output_field=DecimalField()),0)
).annotate( leadtime=ExpressionWrapper(F('lead_time'), output_field=DecimalField())
).exclude(dontshow__gte=0).exclude(leadtime=0)
Эти строки были добавлены в мою основную модель:
objects = models.Manager()
toorderobjects = ToOrderManager()
и мой views.py теперь выглядит так:
def toorder(request):
sorted=Itemslist.toorderobjects.all()
context={ 'sorted': sorted }
return render(request, 'toorder.html', context)
Однако в моем случае, похоже, мне придется выполнять необработанные запросы в моем случае из-за сложных вычислений.
Большое спасибо за обмен знаниями !!!