2013-01-31 48 views
0

我開始使用django。 在我的項目中,我使用MPTT。mptt TreeNodeChoiceField已過濾

我有一個相當簡單的模型。

  • 類別:(樹)
  • 產品1:引用和外鍵的類別。

我添加根部到分類模型,只是爲了簡化用於基本類別尋找一個特定的產品

models.py

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

    @property 
    def root(self): 
     return self.get_root().name 

class Product1(models.Model): 
    ref = models.CharField(max_length=200, blank=True) #YVX2311 
    category = TreeForeignKey(Category) 

admin.py

admin.site.register(Category, MPTTModelAdmin) 
admin.site.register(Product) 

我想修改管理表單,以便能夠說出類似的內容。

models.ForeignKey(分類,limit_choices_to = {根: '有些 類別產品1'})

當然,這是不可能的,但它確實說明了我想要的東西。

我希望能夠過濾TreeChoiseField,只顯示一些基於模型屬性(本例中爲root)的分支。

謝謝

回答

0

經過多次爭論,我找到了一個解決方案。 我不認爲這是做到這一點的最佳方式,但據我所見,它的工作原理。

我重載MPTT TreeNodeChoiceField和複製的TreeForeignKeyFiltered

在產品上,我改變了foreingkey爲

類別= TreeForeignKeyFiltered(分類,根='主板的)

我將根關鍵字添加到TreeForeingKeyFiltered

class TreeForeignKeyFiltered(models.ForeignKey): 
    """ 
    Extends the foreign key, but uses mptt's ``TreeNodeChoiceField`` as 
    the default form field. 

    This is useful if you are creating models that need automatically 
    generated ModelForms to use the correct widgets. 
    """ 

    def __init__(self, *args, **kwargs): 
     self._root = kwargs.pop('root', None) 
     super(TreeForeignKeyFiltered, self).__init__(*args, **kwargs) 

    def formfield(self, **kwargs): 
     """ 
     Use MPTT's ``TreeNodeChoiceField`` 
     """ 
     kwargs.setdefault('root', self._root) 
     kwargs.setdefault('form_class', TreeNodeChoiceFieldFiltered) 
     return super(TreeForeignKeyFiltered, self).formfield(**kwargs) 

最後我加入了TreeNodeChoiceFieldFiltered作爲

class TreeNodeChoiceFieldFiltered(TreeNodeChoiceField): 
    def __init__(self, queryset, *args, **kwargs): 
     _root = kwargs.pop('root', None) 

     if _root is not None: 
      pid = None 
      for i in queryset: 
       if i.root.name == _root: 
        pid = i.tree_id 
        break 

      if pid is not None: 
       queryset = queryset.filter(tree_id = pid) 

     super(TreeNodeChoiceFieldFiltered, self).__init__(queryset, *args, **kwargs) 

現在我可以通過關鍵字根將在管理表單過濾posibilities的foreingkey。

同樣,我不知道這是否是最好的方法。當然它可以更清潔....