2013-02-27 79 views
2

我有一个模型,在我的Django项目如下:遍历父ForeignKey的

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

    def __unicode__(self): 
     return self.category 

我使用它来设置类别heirachy。有些类别的父类别有一个父类别也有一个父类别等。我想知道如何循环这个结构在方法?

干杯, 本

UPDATE: 下面是我的结构,我的类别表:

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

从阿米尔阿德南的 “GET_NAME” 函数返回:

Parent 
Sub Parent -> Sub Sub Parent 
Sub Sub Parent 

我需要它像这样显示:

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

任何想法?

+0

此外,如果你想拥有自我指涉键,你可以做到这一点'models.ForeignKey(“自我”,空=真,空=真)' – 2013-02-27 21:23:07

回答

3

你所描述的是一个树状结构,并遍历的递归外键关系的所有父元素不幸的是一个非常昂贵的操作;父母的每次查找都需要一次数据库命中,因为其他答案显示了做法。

我会建议你做的却是用一个表结构,可实现有效的树查询。有几种方法可以做到这一点,但要指出你正确的方向,我会建议看看django-mpttdjango-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) 
+0

非常感谢您的帮助。 – 2013-03-03 06:33:14

+1

更多示例在这里:https://code.djangoproject.com/wiki/ModifiedPreorderTreeTraversal – 2013-03-07 02:55:32

3

如何..

def __unicode__(self): 
     str = self.category 
     obj = self 
     while obj.parentCateogry: 
      str += " " + obj.parentCategory.category 
      obj = obj.parentCategory 
     return str 
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() 
+0

嗯差不多了..除非它是一种逆转..如果它是父母,则显示孩子..但孩子不会显示父母。我其实只是想让它向父母显示它是否有一个。 – 2013-02-28 02:26:13