Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.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,我真的很困惑这里发生了什么。我有一个定义如下的类: class Profile(models.Model): user = models.OneToOneField(User) primary_phone = models.CharField(max_length=20) address = models.ForeignKey(Address) @property def primary_email(self): return self.user.ema

我真的很困惑这里发生了什么。我有一个定义如下的类:

class Profile(models.Model):
    user = models.OneToOneField(User)
    primary_phone = models.CharField(max_length=20)
    address = models.ForeignKey(Address)

    @property
    def primary_email(self): return self.user.email
    @primary_email.setter
    def primary_email(self, val): self.user.email = val
注意:用户具有电子邮件属性

现在从命令行开始,我正在尝试:

>>> u = User.objects.get(pk=1)
>>> u.email = 'xxx'
>>> u.profile.primary_email
u'yyy'
它给出了一个不同的值?特别是,u.email的旧价值。发生什么事?这怎么可能?我基本上只是想为电子邮件创建一个别名

更多信息:

>>> id(u) == id(u.profile.user)
False
>>> u
<User: mark>
>>> u.profile.user
<User: mark>
但是u.save不会成功,因为你u、 无论出于何种原因,profile.user。我想这回答了我的问题,但还是有点蹩脚


这两个对象在Python中引用同一个对象是可能的,对吗?这只是Django中一个有趣的设计决定,导致了这一点?

我不是Django用户,但我猜这是因为你在更改u.E.电子邮件后没有更新模型。在通过配置文件访问用户的电子邮件之前,请尝试调用u.save或其他方法

您可以使用Django的特性构建一个变通方法。基本上,当用户发送以下信息时更新Profile.user:

您仍然需要调用User.save以使其正常工作,并且删除Profile.User可能会有其他副作用。也许会有一种更像Django-y的方式;一个拥有比我更多Django经验的人可能会发布它。例如,可以将第一次访问User.profile时调用的代码挂钩,并将profile.User设置为父用户,而不是创建新用户


或者,每当您通过Users.objects.get和reference Users.profile获取用户时,请使用user.profile中的user属性替换用户对象。

我不是Django用户,但我猜这是因为您在更改u.email后没有更新模型。在通过配置文件访问用户的电子邮件之前,请尝试调用u.save或其他方法

您可以使用Django的特性构建一个变通方法。基本上,当用户发送以下信息时更新Profile.user:

您仍然需要调用User.save以使其正常工作,并且删除Profile.User可能会有其他副作用。也许会有一种更像Django-y的方式;一个拥有比我更多Django经验的人可能会发布它。例如,可以将第一次访问User.profile时调用的代码挂钩,并将profile.User设置为父用户,而不是创建新用户


或者,无论何时通过Users.objects.get和reference Users.profile获得用户,都可以使用user.profile中的user属性替换user对象。

django模型中的Python属性本身,因为django的模型在设置实例属性方面发挥了一些魔力。这可能会产生影响。

django模型中的Python属性本身,因为django的模型在设置实例属性方面发挥了一些魔力。也许这会产生影响。

创建User.profile的代码在哪里?idu==idu.profile.user?@outis:It's here:user=models.onetoonefeelduser。Django就是这么神奇。创建User.profile的代码在哪里?idu==idu.profile.user?@outis:It's here:user=models.onetoonefeelduser。Django就是这么神奇的。你猜它是u.save是对的,但那不起作用。不管怎样,打印美国电子邮件而不保存将打印xxx。我认为对于属性,它将引用完全相同的实例变量?u.profile.user很可能引用DB对象周围的包装器;idu==idu.profile.user将告诉您更多信息,检查各种对象的属性也是如此。我不知道这个id函数。你说得对,他们不一样。编辑得不错。那可能有用。。。不管怎么说,这真的只是一个方便的地方。这没什么大不了的。希望它是一致的,以便电话和电子邮件属性都显示在个人资料上,而不是一个在这里,一个在那里。你猜它是u.save是正确的,但这不起作用。不管怎样,打印美国电子邮件而不保存将打印xxx。我认为对于属性,它将引用完全相同的实例变量?u.profile.user很可能引用DB对象周围的包装器;idu==idu.profile.user将告诉您更多信息,检查各种对象的属性也是如此。我不知道这个id函数。你说得对,他们不一样。编辑得不错。那可能有用。。。不管怎么说,这真的只是一个方便的地方。这没什么大不了的。希望它是一致的,以便电话和电子邮件属性都出现在个人资料上,而不是一个在这里,一个在那里。
>>> u.profile.primary_email = 'yyy'
>>> u.profile.user.save()
# models.py
...
def update_user(**kwargs):
    kwargs['instance'].profile.user = kwargs['instance']

models.signals.post_save.connect(update_user, sender=User)