Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.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 为什么可以';我不能将uu getattr_uu与Django模型一起使用吗?_Python_Django_Django Models_Getattr - Fatal编程技术网

Python 为什么可以';我不能将uu getattr_uu与Django模型一起使用吗?

Python 为什么可以';我不能将uu getattr_uu与Django模型一起使用吗?,python,django,django-models,getattr,Python,Django,Django Models,Getattr,我在网上看到过人们使用Django模型的例子,但每次尝试都会出错。(Django 1.2.3) 在普通对象上使用\uuu getattr\uuuu时,我没有任何问题。例如: class Post(object): def __getattr__(self, name): return 42 很好用 现在,当我尝试使用Django模型时: from django.db import models class Post(models.Model): def _

我在网上看到过人们使用Django模型的例子,但每次尝试都会出错。(Django 1.2.3)

在普通对象上使用
\uuu getattr\uuuu
时,我没有任何问题。例如:

class Post(object):
     def __getattr__(self, name):
         return 42
很好用

现在,当我尝试使用Django模型时:

from django.db import models
class Post(models.Model):
     def __getattr__(self, name):
         return 42
并在解释器上进行测试:

以下回溯可能已损坏 或无效错误消息为:('EOF 多行语句',(6,0))

---------------------------------------------------------------------------类型错误
回溯(最近一次呼叫最后一次)

/用户/josh/project/ 在()

/Users/josh/project/lib/python2.6/site-packages/django/db/models/base.pyc 在初始化中(self,*args,**kwargs) 338如果kwargs: 339 raise TypeError(“%s”是无效的关键字 此函数的参数“% kwargs.keys()[0]) -->340信号。初始发送后发送(发送方=自身。, 实例=自身) 341 342 def报告(自我):

/Users/josh/project/lib/python2.6/site-packages/django/dispatch/dispatcher.pyc 在发送中(self、sender、**已命名) 160 161对于自身中的接收者。_live_接收者(_make_id(发送者)): -->162响应=接收器(信号=自身,发送方=发送方, **(已命名) 163响应。追加((接收器,响应)) 164回复

/用户/josh/project/python2.6/site-packages/photologue/models.pyc 在add_方法中(发送方、实例、, 信号,*args,**kwargs) 728 """ 729如果hasattr(实例'add_accessor_methods'): -->730实例。添加\u访问器\u方法() 731 732#将add_accessor_methods函数连接到 后初始化信号

TypeError:“int”对象不可用 可调用

有人能解释一下发生了什么事吗


编辑:我可能在示例中过于抽象,下面是一些更接近我在网站上实际使用的代码:

class Post(models.Model):
    title = models.CharField(max_length=255)
    slug = models.SlugField()
    date_published = models.DateTimeField()
    content = RichTextField('Content', blank=True, null=True)
    # Etc...

Class CuratedPost(models.Model):
    post = models.ForeignKey('Post')
    position = models.PositiveSmallIntegerField()

    def __getattr__(self, name):
        ''' If the user tries to access a property of the CuratedPost, return the property of the Post instead...  '''
        return self.post.name

    # Etc...

虽然我可以为Post类的每个属性创建一个属性,但这会导致大量代码重复。此外,这意味着无论何时我添加或编辑Post类的属性,我都必须记住对CuratedPost类进行相同的更改,这似乎是导致代码腐烂的原因。

Django发送了某些信号ls当模型第一次初始化时(即,通过加载shell)——通过使调用
\uuu getattr
总是返回一个整数,您以Django信号不期望的方式修改了代码(因此,它们正在中断)

如果您想这样做,可以这样尝试:

def __getattr__(self, attr):
  if hasattr(self, attr):
    return super(MyModel, self).__getattr__(attr)
  return 42

必须小心使用uu getattr uu。只截取您知道的,让基类处理您不知道的

第一步是,您可以使用属性来代替吗?如果您想要返回42的“随机”属性,那么这更安全:

class Post(...):
  @property
  def random(self):
    return 42
如果您想让“random”*(如“random\u 1”、“random\u 34”等)做一些事情,那么您必须像这样使用\uuuu getattr\uuuu:

class Post(...):
  def __getattr__(self, name):
    if name.startswith("random_"):
      return name[7:]
    return super(Post, self).__getattr__(name)

这不起作用,因为hasattr(self,attr)以递归方式调用_getattr__。您想要“attr in self.”__事实上,这也行不通,因为只有当attr不在dict中时才会调用uuu getattr。安德鲁:听起来你可以用
\uu getattribute\uuu
来实现这一点,though@Cameron:uuu getattribute_uuu也很棘手,只是方式不同。我怀疑@Joshmaker应该使用一个属性来代替它。“Return 42”只是一个例子,
\uu getattr\uu
无论返回什么都会中断。我看到过旧的Django项目的代码示例,这些项目使用
\uuuu getattr\uuuu
没有问题,而且我找不到任何文档表明它已被弃用。我在文章中使用的示例应该表明,即使是非常简单的getattr属性应用程序,在扩展Django模型对象时也会中断。我已经更新了我的原始帖子,加入了一些更接近我实际使用的内容。我不相信这对Django会起作用,因为models.Model没有
\uuuu getattr\uuuuuuuuu
,所以你的
超级(post,self)。\uu getattr\uuuuuuuuuuuuu(…)
应该抛出异常。你尝试过吗?Python提供了一个默认的getattr,所以它“应该”不是问题。这真的是“返回self.post.name”吗?它应该是“return getattr(self.post,name)”,实际上,如果
name
输入本身就是
“post”
,那么代码应该使用类似的模式遇到无限递归问题。
class Post(...):
  @property
  def random(self):
    return 42
class Post(...):
  def __getattr__(self, name):
    if name.startswith("random_"):
      return name[7:]
    return super(Post, self).__getattr__(name)