Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python变量引用意外地改变了行为_Python_Django - Fatal编程技术网

python变量引用意外地改变了行为

python变量引用意外地改变了行为,python,django,Python,Django,我想了解这种完全出乎意料的行为改变的原因是什么,以及如何实施。我来自JS世界,这很可能不可能以任何方式实现 通过遍历对象调用fn会得到与首次将此对象分配给新变量时不同的结果: >>> from core.models import SomeModel >>> s = SomeModel.objects.get(id=45) >>> s.user.profile.needs_review True >>> s.user.pro

我想了解这种完全出乎意料的行为改变的原因是什么,以及如何实施。我来自JS世界,这很可能不可能以任何方式实现

通过遍历对象调用fn会得到与首次将此对象分配给新变量时不同的结果:

>>> from core.models import SomeModel
>>> s = SomeModel.objects.get(id=45)
>>> s.user.profile.needs_review
True
>>> s.user.profile.needs_review = False
>>> s.user.profile.needs_review
True
>>> profile = s.user.profile
>>> profile.needs_review
True
>>> profile.needs_review = False
>>> profile.needs_review
False
这确实令人不安,因为在我使用过的任何语言中,这都会执行类似的操作

顺便说一句,这是一个常规的django模型,但我更感兴趣的是知道可以使用什么样的语言资源来实现这种效果

为了更好地解释我为什么会这样做,我尝试通过执行以下操作在
配置文件
模型上进行常规保存:

streamer.user.profile.needs_review = True
streamer.user.profile.save()
它没有起作用,但做了:

profile = streamer.user.profile
profile.needs_review = True
profile.save()

工作正常。

如果对模型对象进行更改,则必须保存该对象,否则它将无法反映

>>> s.user.profile.needs_review = False
>>> s.save()
>>> s.user.profile.needs_review
False
下一行

>>> profile = s.user.profile
>>> profile.needs_review
True

它不会从数据库加载新数据,所以这就是为什么您会看到这种行为

关于允许这种行为的python语言资源,您可以检查:


基本上,django使用它来抽象数据库查询,在您的示例中不作为常规对象。

请显示您的
用户
模型。这是django的标准用户模型。如果运行
.save(),它是否会更改
更改字段后?遍历外键关系将从数据库加载对象。如果没有持久化更改(对对象调用
.save()
),则会从数据库中加载一个新副本,该副本没有您刚才所做的更改。最好保留对该对象的本地引用,进行更改并保存,而不重新遍历图形。例如,
streamer.save()
也会保留更改,您的错误是再次遍历
streamer.user.profile
。@enapupe:类似于什么?遍历、数据库数据反射、检测属性更改?我想我不清楚的是为什么将其分配给新变量会改变一切。当您将其分配给新变量时,它将执行属性的
getter
功能,创建您正在编辑的对象的实例。不指定时,仍使用父对象。尽管如此,它并没有解释这种行为,但它在Django代码中。
class C:
    def __init__(self):
        self._x = None

    @property
    def x(self):
        """I'm the 'x' property."""
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

    @x.deleter
    def x(self):
        del self._x