gpt4 book ai didi

django - 将参数传递给迭代查询集中对象模型类的 __init__

转载 作者:行者123 更新时间:2023-12-03 21:16:57 26 4
gpt4 key购买 nike

我有一个被覆盖的模型 __init__像这样的方法:

class MyModel(models.Model):
...

def __init__(self, *args, **kwargs):
if not kwargs.get('skip', False):
do_something()
super().__init__(*args, **kwargs)

如何通过 skip论据 __init__ ,当我迭代查询集时:
data = [obj for obj in MyModel.objects.all()]

我想通过自定义管理器中的方法来实现这个,使用这样的东西: queryset.with_skip()

最佳答案

我看到您没有删除参数 skip来自 kwargs在将其传递给 super().__init__ 之前.这意味着“skip”是字段名称,否则您会得到异常 TypeError("'skip' is an invalid keyword argument for this function") .

如果您真的需要do_something()当对象在使用之前创建如此不可或缺以至于没有人应该忘记避免所有不受支持的方式(??)然后自定义管理器等是不够的。

你的问题是 models.Model.__init__(...)两者都支持 *args**kwargs论点如此完美,以至于它们应该可以互换。你打破了它,如果“跳过”是由位置参数的完整元组传递的,你就忽略它。也就是说,如果对象是从数据库创建的。阅读文档 Customizing model loading :

... If all of the model’s fields are present, then values are guaranteed to be in the order __init__() expects them. That is, the instance can be created by cls(*values)...
.
| @classmethod
| def from_db(cls, db, field_names, values):
| ...
| instance = cls(*values)
| ...



修复它的一个简单方法是调用 do_something()之后 super().__init__并阅读 self.skip而不是同时解析 kwargs 和 args。
    def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if not self.skip:
do_something()

问题可能是在 super().__init__ 末尾发送的信号“post_init”如果你需要它。

最后一种可能是支持 *args (hacky,但仍然以某种方式使用记录的名称):
    def __init__(self, *args, **kwargs):
if kwargs:
skip = kwargs.get('skip', False)
else:
# check "val is True" in order to skip if val is DEFERRED
skip = any(field.name == 'skip' and val is True
for val, field in zip(args, self._meta.concrete_fields)
)
if not skip:
do_something()
super().__init__(*args, **kwargs)

编辑:也许你不需要你想要的东西和一个 Proxy model有时可以在同一个数据库表中的相同数据的基本模型上做一些额外的事情是正确的解决方案。 (“跳过”看起来不像是描述对象数据的名称,而是描述对象创建模式的名称。测试和维护子类比内部的神秘开关更容易。)

关于django - 将参数传递给迭代查询集中对象模型类的 __init__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45995549/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com