2013-01-31 1 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) 
에 대한 기본 범주에 대한 검색을 단순화하기 위해, 카테고리 모델에 루트를 추가

나는 무엇을 말하고 싶다면 admin 양식을 수정하는 것이 좋습니다.

models.ForeignKey (종류, limit_choices_to = {루트 '제품 1에 대한 일부 카테고리'}) 물론

이 불가능하지만 내가 원하는 것을 설명 않습니다.

모델의 속성 (이 경우 루트)을 기반으로 일부 분기 만 표시하도록 TreeChoiseField를 필터링 할 수 있기를 원합니다.

감사합니다.

답변

0

많은 스크램블을 한 후에 해결책을 찾았습니다. 이것이 최선의 방법이라고 생각하지 않지만, 내가 볼 수있는 한, 효과가 있습니다.

내가 mptt TreeNodeChoiceField 과부하 및 제품에서 TreeForeignKeyFiltered

복사, 나는

카테고리 = TreeForeignKeyFiltered (종류, 루트 = '마더')

I의 foreingkey 변경 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) 
,210

그리고 마침내 나는 이제 관리자 형태로 posibilities를 필터링 할 foreingkey에 키워드 루트를 통과 할 수

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) 

로 TreeNodeChoiceFieldFiltered을 추가했다.

다시 말해서 이것이 최선의 방법인지는 잘 모르겠습니다. 물론 청소기가 될 수 있습니다 ....