首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python/django:将类方法传递给类变量

python/django:将类方法传递给类变量
EN

Stack Overflow用户
提问于 2022-08-05 01:17:18
回答 1查看 62关注 0票数 0

因此,我正在使用django-models,我希望传递类所传递的对象数量,然后将其作为模型参数传递,类似于

代码语言:javascript
复制
class someclass:
    somevar = 'somevalue'
    
    def retrieve1():
        return somevar

    def retrieve2(self):
        return self.somevar

    def retrieve3():
        return someclass.somevar

    #returns NameError: name 'somevar' is not defined
    value1 = retrieve1()
    
    #returns TypeError: retrieve2() missing 1 required positional argument: 'self'
    value2 = retrieve2()
    
    #returns NameError: name 'someclass' is not defined
    value3 = retrieve3()

我甚至尝试用somevar作为实例传递__init__,但是没有什么好的:

代码语言:javascript
复制
class someclass:
    def __init__(self):
        self.somevar = 'somevalue'
    
    #returns NameError: name 'self' is not defined
    value = self.somevar

我在这里错过了什么?!我尝试了每一件事情,比如把这个方法当作@classmethod@staticmethod没有任何帮助。

下面是我正在苦苦挣扎的真正代码:

代码语言:javascript
复制
class Box(models.Model):
    
   #so as u see, i'm trying to get the len of all objects that class holds
    def defaultOrder():
        return len(Box.objects.all()) + 1

    name = models.CharField(max_length=100, unique=True)
    order = models.IntegerField(
        blank=False, 
        unique=True,
       
       #here will be passed
        default= defaultOrder()
    )
    end_days = models.IntegerField(blank=False)
    end_hours = models.IntegerField(blank=False)
    end_minutes = models.IntegerField(blank=False)
    def __str__(self):
        return self.name

就像你看到的那样,我只想像对待外面的人一样对待这门课!很难用CS的方式来解释,我希望你能理解.

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-05 06:58:20

你要求的是根本不可能的。在创建类之前,您正在尝试使用它。也就是说,在创建Box类之前,您正在调用defaultOrder()

看起来,您正在尝试实现一个自动递增序列,类似于主键。主键通常以id的形式公开。但是如果你愿意的话,你可以给这个领域另一个名字。例:

代码语言:javascript
复制
class Box(models.Model):
    order = models.fields.AutoField(primary_key=True)

令人烦恼的是,django只允许模型有一个AutoField,因此您不能为默认的id字段创建一个单独的id字段。如果您希望AutoField是可变的,那么您可能需要第二个order,以便您可以在需要的情况下重新排序框。这是双重烦人的,因为在SQL中直接实现这样的东西是微不足道的。在PostgreSQL中,您可能会执行如下操作:

代码语言:javascript
复制
CREATE TABLE box(
    box_id SERIAL PRIMARY KEY, -- serial is an auto-incrementing 32-bit integer
    "order" SERIAL NOT NULL,
    content TEXT,
    CONSTRAINT box_order_unique UNIQUE ("order") DEFERRABLE INITIALLY IMMEDIATE
);

INSERT INTO box (content) VALUES ('a'), ('b'), ('c');
SELECT * FROM box ORDER BY "order";

给予:

代码语言:javascript
复制
box_id  order   content
1       1       a
2       2       b
3       3       c

然后你就可以做这样的事情:

代码语言:javascript
复制
BEGIN;
SET CONSTRAINTS box_order_unique DEFERRED;
UPDATE box SET "order" = 2 WHERE content = 'c';
UPDATE box SET "order" = 3 WHERE content = 'b';
COMMIT;
SELECT * FROM box ORDER BY "order";

给予:

代码语言:javascript
复制
box_id  order   content
1       1       a
3       2       c
2       3       b

在Django传递可调用的

default可以是可调用的。我认为这实际上是你想要的行为。每次插入Box时,都希望它的值是Box表中行的当前计数,而不仅仅是静态默认值。这是可行的,因为函数只有在创建类之后才会被调用。

代码语言:javascript
复制
class Box(models.Model):
    def defaultOrder():
        # NB. count() requires less work by database than all(), and also less
        # data to be transferred from the
        return len(Box.objects.count()) + 1

    order = models.IntegerField(
        blank=False, 
        unique=True,
        # here will be passed -- NB. No brackets!
        default=defaultOrder
    )

这有一个不希望产生的副作用,即每次插入都会导致额外的往返到数据库。再次恼人,因为我们知道这是数据库可以自己处理的事情。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73243699

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档