我正在尝试使用以下代码片段在运行时动态添加属性:
...
for appellation in queryset:
if appellation.id in used_id_set:
appellation.is_used_flag()
print(appellation.is_used)
# prints true as expected
else:
appellation.is_not_used_flag()
first = queryset.first()
print(first.is_used)
# prints AttributeError: 'Appellation' object has no attribute 'is_used'
...
def is_used_flag(self):
self.is_used = True
def is_not_used_flag(self):
self.is_used = False
为什么在循环中它为什么能正常工作,但是当我尝试从实例中检索属性后却无法工作时,为什么呢?我使用setattr appellation.is_used = True
和修改__dict__
遇到了相同的问题。还有没有更好的方法可以做到这一点?
我引用了以下帖子:
Why can't you add attributes to object in python?我确实有一个字典,但循环后似乎并没有“持久”
How to assign a new class attribute via __dict__?与上述问题相同
Dynamically defining instance fields in Python classes与上面相同
由于两个答案都提及相似的内容,因此我应该阐明我的意图。我不想在数据库中实际保留该值。我只想序列化它并在前端使用它。
答案 0 :(得分:1)
django中的Queryset API(通常)会返回其他查询集,这些查询集又会通过访问数据库进行评估。通过执行queryset.first()
,您正在执行另一个尚未设置属性的数据库调用。
如果您需要在查询集之间保存这个is_used
标志(坚持更改),建议您在模型上添加一个BooleanField,或者找到另一种方法来完成您想要的操作,因为在内存中,使用queryset API不会返回属性。
答案 1 :(得分:0)
如果您希望更改保留下来,则需要在设置self.save()
之后调用is_used
,并假设is_used
是Appellation
模型上的一个字段。
models.py
from django.db import models
class Appellation(models.Model):
# ... rest of code ...
is_used = models.BooleanField(default=False)
def is_used_flag(self):
self.is_used = True
self.save()
def is_not_used_flag(self):
self.is_used = False
self.save()
请注意,Django实例仍然是Python对象,因此动态添加属性将以相同的方式工作,这就是为什么它按您提供的代码中的预期打印True
的原因。