Django技术问询:如何检查页面对象是否存在父级与祖父级?
正确检查Django页面模型的父级与祖父级存在性
你的错误根源在于直接链式访问可能为None的对象属性,以及误用了exists方法:
- 当页面没有父级时,
self.object.parent是None,此时访问self.object.parent.parent会直接抛出'NoneType' object has no attribute 'parent'错误。 exists是Django QuerySet的方法,单个模型对象(或None)没有这个属性,所以self.object.parent.parent.exists会报错。
正确实现方式
必须逐层判断存在性,先确认父级不为None,再检查祖父级:
def get_success_url(self): # 先检查父级存在,再检查祖父级 if self.object.parent and self.object.parent.parent: return reverse('about:detail', kwargs={ 'grandparent': self.object.parent.parent.slug, 'parent': self.object.parent.slug, 'page': self.object.slug }) # 仅存在父级的情况 elif self.object.parent: return reverse('about:detail', kwargs={ 'parent': self.object.parent.slug, 'page': self.object.slug }) # 无父级与祖父级的情况 else: return reverse('about:detail', kwargs={'page': self.object.slug})
优化写法(使用getattr避免链式访问)
如果层级更深,用getattr可以更简洁地处理可能为None的情况,它的第三个参数会在属性不存在时返回默认值:
def get_success_url(self): # 逐层获取父级、祖父级,不存在则返回None parent = getattr(self.object, 'parent', None) grandparent = getattr(parent, 'parent', None) if parent else None if grandparent: return reverse('about:detail', kwargs={ 'grandparent': grandparent.slug, 'parent': parent.slug, 'page': self.object.slug }) elif parent: return reverse('about:detail', kwargs={ 'parent': parent.slug, 'page': self.object.slug }) else: return reverse('about:detail', kwargs={'page': self.object.slug})
关键注意点
- 永远不要假设关联对象一定存在,必须先判断对象不为
None,再访问其属性。 exists()仅用于QuerySet(比如Page.objects.filter(...)),单个模型实例或None不能使用该方法。
内容的提问来源于stack exchange,提问作者Michael Romanov
相关产品推荐
相关产品推荐

