遍历父级外键

3 投票
3 回答
981 浏览
提问于 2025-04-17 17:22

我在我的Django项目中有一个模型,结构如下:

class Category(models.Model):
   parentCategory = models.ForeignKey(Category,null=True,blank=True)
   category = models.CharField(max_length=255)

   def __unicode__(self):
       return self.category

我用这个模型来设置分类层级。有些分类的父分类又有自己的父分类,依此类推。我在想,如何在__unicode__方法中遍历这个结构呢?

谢谢,
Ben

更新:以下是我分类表中的结构:

Parent
Parent -> Sub Parent
Parent -> Sub Parent -> Sub Sub Parent

Aamir Adnan的“get_name”函数返回的是:

Parent
Sub Parent -> Sub Sub Parent
Sub Sub Parent

我希望它显示成这样:

Parent
Parent -> Sub Parent
Parent -> Sub Parent -> Sub Sub Parent

有什么想法吗?

3 个回答

1

你可以这样做:

class Category(models.Model):
    parentCategory = models.ForeignKey('self', null=True, blank=True,
        related_name="categories")
    category = models.CharField(max_length=255)

    def get_name(self, obj, name=''):
        name += ' - ' + obj.category
        categories = obj.categories.all()
        if categories:
            for category in categories:
                name = self.get_name(category, name)
            return name
        else:
            return name

    def __unicode__(self):
        return self.get_name(self).strip(' - ').strip()
3

那怎么样呢……

   def __unicode__(self):
       str = self.category
       obj = self
       while obj.parentCateogry:
            str += " " + obj.parentCategory.category 
            obj = obj.parentCategory
       return str
3

你所描述的是一种树形结构,而遍历所有父元素的递归外键关系其实是个很费劲的操作;每次查找父元素都需要访问数据库,这样会消耗很多资源,其他回答也展示了不同的处理方法。

我建议你使用一种能高效处理树形查询的表结构。有几种方法可以做到这一点,但为了让你找到正确的方向,我推荐你看看 django-mptt 或者 django-treebeard

举个例子,使用django-mptt,你可以通过以下这种通用结构来实现,这样只需额外访问一次数据库就能查询到目标类别的所有祖先。

from django.db import models
from mptt.models import MPTTModel, TreeForeignKey


class Category(MPTTModel):
    name = models.CharField(max_length=255)
    parent = TreeForeignKey('self', null=True, blank=True, related_name='children')

    def __unicode__(self):
        ancestors = self.get_ancestors(ascending=False, include_self=True)
        return ' -> '.join(category.name
                           for category in ancestors)

撰写回答