我在产品和类别之间存在多对多的关系。我正在使用mpt来管理管理员上的类别显示(工作正常),因此我可以将产品分配到类别。
虽然这些类别工作正常但是我遇到问题的产品方面。
在我的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},
}
这几乎完成了工作,但所有类别都显示了复选框,这不是我想要的,因为您不想将产品添加到具有子类别的类别。
我想要的是显示类别,这样您只能将产品添加到没有子项的类别中,因此在此示例中
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
非常感谢您的帮助!
更新
嗨,我意识到我的问题可能太宽泛了!
作为一个Django新手,我认为我需要做的是创建一个可能覆盖CheckboxSelectMultiple小部件的自定义小部件,我可以将其应用于我的'categories'模型属性。
目前,我正在使用如上所述的TreeManyToManyField的formfield_overrides
formfield_overrides = {
TreeManyToManyField:{'widget':CheckboxSelectMultiple},
}
这不仅没有给出所需的结果,而且还没有为所有TreeManyToMany字段使用标准的CheckboxSelectMultiple,我可以仅为我的'categories'属性指定这个小部件吗?
尽管如此,是否可以向我展示如何创建自定义窗口小部件,传递有关类别树和选定状态的信息(对于已分配给类别的产品)?我一直试图对此进行排序,但一直在努力 - 任何帮助都非常感激!
关于KARANTSTHR评论的更新
以下是类别的截图 - 所有类别都显示没有子项的类别,但我们是否可以在标签中向父母显示这些类别,如上所述?
向KARANTSTHR更新2
以下是您实施的屏幕截图。
答案 0 :(得分:2)
ModelAdmin非常灵活,您可以在ProductAdmin(表单为ModelAdmin选项)中为表单选项指定自定义ModelForm,以过滤掉没有任何子类别的类别。
所以,
我认为您不需要自定义小部件来解决您的问题,只需将 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
您需要在 models.py
中的ProductCategory类的父字段中添加related_name
因此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
您可以更改ProductCategory的 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])
请注意,这不是获取您选择的标签(对象名称)的激进方法,如果我找到更好的解决方案,我会更新我的答案。