Jos*_*ker 9 python django django-models getattr
我在网上看过人们使用__getattr__Django模型的例子,但每当我尝试时我都会遇到错误.(Django 1.2.3)
我__getattr__在普通物体上使用时没有任何问题.例如:
class Post(object):
def __getattr__(self, name):
return 42
Run Code Online (Sandbox Code Playgroud)
工作得很好......
Run Code Online (Sandbox Code Playgroud)>>> from blog.models import Post >>> p = Post() >>> p.random 42
现在,当我尝试使用Django模型时:
from django.db import models
class Post(models.Model):
def __getattr__(self, name):
return 42
Run Code Online (Sandbox Code Playgroud)
并在解释器上测试它:
Run Code Online (Sandbox Code Playgroud)>>> from blog.models import Post >>> p = Post() ERROR: An unexpected error occurred while tokenizing input The跟踪回溯可能已损坏或无效错误消息为:('多行语句中的EOF',(6,0))
-------------------------------------------------- ------------------------- TypeError
Traceback(最近一次调用最后一次)/ Users/josh/project/in()
/Users/josh/project/lib/python2.6/site-packages/django/db/models/base.pyc in init(self,*args,**kwargs)338如果kwargs:339引发TypeError("'%s '是这个函数"%kwargs.keys()[0])无效的关键字参数- > 340 signals.post_init.send(发件人=自我.类,实例=自我)341 342 DEF 再版(个体):
/Users/josh/project/lib/python2.6/site-packages/django/dispatch/dispatcher.pyc in send(self,sender,**named)160 161 for self._live_receivers(_make_id(sender)): - > 162响应=接收者(信号=自己,发送者=发送者,**命名)163 answers.append((接收者,响应))164返回响应
/Users/josh/project/python2.6/site-packages/photologue/models.pyc in add_methods(sender,instance,signal,*args,**kwargs)728"""729 if hasattr(instance,'add_accessor_methods') : - > 730 instance.add_accessor_methods()731 732#将add_accessor_methods函数连接到post_init信号
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...
Run Code Online (Sandbox Code Playgroud)
虽然我可以为Post类的每个属性创建一个属性,但这会导致大量的代码重复.更进一步,这意味着无论何时我添加或编辑Post类的属性,我都必须记住对CuratedPost类进行相同的更改,这似乎是代码腐烂的一个方法.
必须小心使用__getattr__.只拦截你所知道的,让基类处理你不知道的事情.
第一步是,您可以使用房产吗?如果你想要一个返回42的"随机"属性,那么这样更安全:
class Post(...):
@property
def random(self):
return 42
Run Code Online (Sandbox Code Playgroud)
如果你想要"random_*"(比如"random_1","random_34"等)做某事,你就必须像这样使用__getattr__:
class Post(...):
def __getattr__(self, name):
if name.startswith("random_"):
return name[7:]
return super(Post, self).__getattr__(name)
Run Code Online (Sandbox Code Playgroud)
当模型首次初始化时(即通过加载 shell),Django 会发送某些信号 - 通过使调用__getattr始终返回一个整数,您已经以 Django 信号不期望的方式修改了代码(因此,他们正在打破)。
如果你想这样做,也许可以尝试这样:
def __getattr__(self, attr):
if hasattr(self, attr):
return super(MyModel, self).__getattr__(attr)
return 42
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5063 次 |
| 最近记录: |