在Django项目中。在视图中进行注释时,获取未定义项的错误信息

2024-10-01 02:36:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道,这个问题已经被提到了几次,但我找不到解决问题的办法。因此,请接受我的再次请求道歉

我有一个基于条件的过滤器,它不适合我

这是我的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)

然而,在我的例子中,由于复杂的计算,看起来我将不得不执行原始查询

非常感谢您的知识分享


Tags: pyselfvenvmodelslibpackagesstocksite
1条回答
网友
1楼 · 发布于 2024-10-01 02:36:54

我认为这个dontshow=above_below_ss()不起作用,因为它是一个实例方法,这意味着您首先获取一条记录,然后调用它record.above_below_ss()。 您可以改为使用funcexpression wrapper将此方法作为注释的一部分编写:

型号.py

from django.db.models import Func

class Round(Func):
    function = 'ROUND'
    arity = 2

视图.py

from django.db.models import DecimalField, ExpressionWrapper, F
from .models import Round

sorted=Itemslist.objects.annotate(dontshow=Round(ExpressionWrapper(F('current_stock') - F('safety_stock'), output_field=DecimalField()))).exclude(dontshow__gt=0)

如果您想重用它,可以将查询移动到manager并命名它。然后,不用每次编写长查询,只需使用Itemslist.objects.whatever_name_you_chose()

相关问题 更多 >