这是我写的Django模型类。当我从Django调用get_object_or_404
时,这个类得到了一个keyerror(我认为由于get函数没有将kwargs传递给__init__
而引发了keyerror,所有参数都是位置的)。有趣的是,当我从控制台调用get_object_or_404
时,它不会出错。
我想知道为什么,如果下面的代码是正确的方法(即使用 init 来填充链接字段)来构造这个类。
class Link(models.Model)
event_type = models.IntegerField(choices=EVENT_TYPES)
user = models.ForeignKey(User)
created_on = models.DateTimeField(auto_now_add = True)
link = models.CharField(max_length=30)
isActive = models.BooleanField(default=True)
def _generate_link(self):
prelink = str(self.user.id)+str(self.event_type)+str(self.created_on)
m = md5.new()
m.update(prelink)
return m.hexdigest()
def __init__(self, *args, **kwargs):
self.user = kwargs['user'].pop()
self.event_type = kwargs['event_type'].pop()
self.link = self._generate_link()
super(Link,self).__init__(*args,**kwargs)
答案 0 :(得分:7)
self.user = kwargs['user'].pop()
self.event_type = kwargs['event_type'].pop()
您正尝试从字典中检索条目,然后调用其pop方法。如果要从字典中删除并返回对象,请调用dict.pop()
:
self.user = kwargs.pop('user')
当然,如果KeyError
中不存在"user"
,则kwargs
会失败。您需要为pop提供默认值:
self.user = kwargs.pop('user', None)
这意味着“如果"user"
在字典中,请删除并返回。否则,请返回None
”。
关于其他两行:
self.link = self._generate_link()
super(Link,self).__init__(*args,**kwargs)
super().__init__()
会将link
设置为某个内容,可能是None
。我会颠倒这些界限:
super(Link,self).__init__(*args,**kwargs)
self.link = self._generate_link()
您可能希望在设置链接之前添加测试,以查看它是否已存在(if self.link is not None: ...
)。这样,您传递给构造函数的链接将不会被覆盖。
答案 1 :(得分:2)
没有理由为Django模型类编写自己的__init__
。我想如果没有它我会更开心。
__init__
中您认为想要做的事情几乎可以在save
中完成。
答案 2 :(得分:2)
我认为你根本不需要__init__
。
在实例化类时,您总是在计算链接的值。这意味着您忽略数据库中存储的内容。既然如此,那么为什么还要打扰模型领域呢?最好使用_generate_link
中的代码使用getter将链接作为属性。
@property
def link(self):
....
答案 3 :(得分:1)
想知道为什么,如果下面的代码是正确的方法(即使用
__init__
来填充链接字段)来构造这个类。
我尝试重载__init__
时遇到了一些问题
在maillist我得到了这个答案
最好不要用自己的重载
__init__
。更好的选择是使用a挂钩post_init
信号 自定义方法,并在该方法中执行您的process()
和make_thumbnail()
来电。{/ p>
在你的情况下,post_init信号应该起作用,并且根本不需要实现__init__
。
你可以这样写:
class Link(models.Model)
event_type = models.IntegerField(choices=EVENT_TYPES)
user = models.ForeignKey(User)
created_on = models.DateTimeField(auto_now_add = True)
link = models.CharField(max_length=30)
isActive = models.BooleanField(default=True)
def create_link(self):
prelink = str(self.user.id)+str(self.event_type)+str(self.created_on)
m = md5.new()
m.update(prelink)
return m.hexdigest()
def post_link_init(sender, **kwargs):
kwargs['instance'].create_link()
post_init.connect(post_link_init, sender=Link)
>>> link = Link(event_type=1, user=aUser, created_on=datetime.now(), link='foo', isActive=True)
为unique
提供关键字link = models.CharField(max_length=30, unique=True)
也可能有所帮助。如果未提供,则get_object_or_404可能无法在链接字段中的相同值存在多次的情况下起作用。