2017-07-26 36 views
2

我在产品和类别之间存在多对多关系。我正在使用mptt来管理admin上的类别显示(工作正常),因此我可以将产品分配给类别。Django:使用mptt-django将产品分配给多对多关系中的类别

虽然类别工作正常,但我遇到问题的产品方面。

在我的models.py我已经(截断简洁):

from mptt.models import MPTTModel,TreeForeignKey,TreeManyToManyField 

class ProductCategory(MPTTModel): 
    parent = TreeForeignKey('self', null=True, blank=True) 

class Product(models.Model) 
    categories = TreeManyToManyField(ProductCategory) 

在我的admin.py我有

from django.forms import CheckboxSelectMultiple 
from .models import Product,ProductCategory 
from django.db import models 
from django.contrib import admin 
from mptt.admin import MPTTModelAdmin 
from mptt.models import TreeManyToManyField 

class ProductAdmin(admin.ModelAdmin): 

    formfield_overrides = { 
     TreeManyToManyField:{'widget':CheckboxSelectMultiple}, 
    } 

这几乎可以完成工作,但所有的类都是显示复选框,这是不是我想要的,因为你不想添加产品到具有子类别的类别。

enter image description here

我要的是类别的显示,这样你只能将产品添加到不生孩子的类别,所以在这个例子

Category 1 
Category 2 sub sub 
Category 3 sub 

而唱片公司将

Category 1 
Category 2 > Catgory 2 sub > Category 2 sub sub 
Category 3 > Category 3 sub 

非常感谢您的帮助!

UPDATE

您好,我知道我的问题可能是太广阔!

作为一名Django新手,我想我需要做的是创建一个可能覆盖CheckboxSelectMultiple小部件的自定义小部件,以便将其应用于我的'categories'模型属性。

目前,我使用的TreeManyToManyField formfield_overrides上述

formfield_overrides = { 
    TreeManyToManyField:{'widget':CheckboxSelectMultiple}, 
} 

所讨论这不仅不会得到预期的结果,但也而不是使用标准CheckboxSelectMultiple所有TreeManyToMany领域,我可以指定这个小部件只是为了我的“类别”属性?

尽管如此,有没有可能向我展示如何创建自定义小部件,传递有关类别树和选定状态的信息(对于已分配给类别的产品)?我一直试图自己排序,但一直在挣扎 - 非常感谢任何帮助!

更新后KARANTSTHR COMMENT

这里是类别的截图 - 在显示无子女的类别都好,但我们可以证明父母这些类别的标签如上所述?

enter image description here

Update 2升级到KARANTSTHR

这里是你实现一个屏幕截图。

enter image description here

回答

1

的ModelAdmin非常灵活,您可以在ProductAdmin 形式选项指定自定义的ModelForm(形式的ModelAdmin选项)来过滤掉没有任何子类的类别。
所以, 我觉得你不需要自定义部件来解决问题,只是改变admin.py作为

from django import forms 
from django.forms import CheckboxSelectMultiple 
from .models import Product,ProductCategory 
from django.contrib import admin 
from mptt.admin import MPTTModelAdmin 
from mptt.models import TreeManyToManyField 


class filterCategories(forms.ModelForm): 
    class Meta: 
     model = Product 
     fields = '__all__' 

    def __init__(self,*args,**kwargs): 
     super(filterCategories, self).__init__(*args,**kwargs) 
     self.fields['categories'].queryset = ProductCategory.objects.filter(children=None) 


class ProductAdmin(admin.ModelAdmin): 
    form = filterCategories 
    formfield_overrides = { TreeManyToManyField:{'widget':CheckboxSelectMultiple},} 


admin.site.register(Product,ProductAdmin) 
admin.site.register(ProductCategory,MPTTModelAdmin) 


更新1
需要在父字段添加related_name ProductCategory类的models.py
因此models.py中的ProductCategory类将如下

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

    def __str__(self): 
     return self.name 

更新2
您可以更改产品分类STR方法如下供您选择标签

def __str__(self): 
    try: 
     ancestors = self.get_ancestors(include_self=True) 
     ancestors = [i.name for i in ancestors] 
    except: 
     ancestors = [self.name] 

    return ' > '.join(ancestors[:len(ancestors) + 1]) 

注意,这不是获取标签一个激进的方法(对象的名字),我将会更新我的答案,如果我找到更好的解决方案。

+0

嗨,非常感谢 - 几乎在那里,请参阅我的更新,上面已发布图片。尽管只有没有孩子的类别才能正确显示,是否可以在标签中显示父母? – Newfoundland