我知道,这个问题已经被提到了几次,但我找不到解决问题的办法。因此,请接受我的再次请求道歉
我有一个基于条件的过滤器,它不适合我
这是我的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
,提供的解决方案确实可以解决这个问题
但正如您已经提到的,我需要通过更复杂的函数对数据库进行排序,因此最好在models.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()
my views.py现在看起来像这样:
def toorder(request):
sorted=Itemslist.toorderobjects.all()
context={ 'sorted': sorted }
return render(request, 'toorder.html', context)
然而,在我的例子中,由于复杂的计算,看起来我将不得不执行原始查询
非常感谢您的知识分享
我认为这个
dontshow=above_below_ss()
不起作用,因为它是一个实例方法,这意味着您首先获取一条记录,然后调用它record.above_below_ss()
。 您可以改为使用func和expression wrapper将此方法作为注释的一部分编写:型号.py
视图.py
如果您想重用它,可以将查询移动到manager并命名它。然后,不用每次编写长查询,只需使用
Itemslist.objects.whatever_name_you_chose()
相关问题 更多 >
编程相关推荐