xadmin 管理后台动态添加菜单

一个文章目录表 关联自己 两级结构 ,我想创建在文章目录里添加一条文章类型a 然后xadmin管理后台就会多出一个对应的a菜单 且a菜单里面点击去是所属a的文章,如果a还有子目录b,c的话 在a菜单下添加文章 选择文章目录只出现a对应的子目录
实现如下

model如下

class ArticleType(models.Model):
    menu=models.ForeignKey('ArticleType',null=True,blank=True)
    name=models.CharField(max_length=128,verbose_name="名称",null=True,blank=True)
    banner=models.ImageField(verbose_name='banner',null=True,blank=True)
    class Meta:
        verbose_name = '目录'
        verbose_name_plural = '目录'
    def __unicode__(self):
        return '%s' % (self.name)

class Article(models.Model):
    article_type=models.ForeignKey(ArticleType,verbose_name='所属目录',blank=True,null=True)
    title = models.CharField(max_length=255, verbose_name='文章标题', blank=True)
    desprition = models.CharField(verbose_name='文章简介', max_length=255, blank=True)
    image = models.ImageField(u'文章配图', blank=True)
    articleUrl = models.CharField(verbose_name='链接地址', max_length=255, blank=True)
    content = models.TextField(u'内容', blank=True)
    display_sort = models.IntegerField(u'排序', blank=True, null=True)
    createtime = models.DateTimeField(verbose_name=u'时间', auto_now_add=True)
    class Meta:
        verbose_name = '文章'
        verbose_name_plural = '文章'
        ordering = ['display_sort']
    pass
    def __unicode__(self):
        return '%s' % (self.title)

adminx 如下

class artTypeAdmin(object):
    list_display=[f.name for f in ArticleType._meta.fields]
    def queryset(self):
            return self.model.objects.filter(menu=None)

    def save_models(self):
        flag = self.org_obj is None and 'create' or 'change'
        self.new_obj.save()
        ca = categoryAdmin(ArticleType, Article)
        m=ca.createModel(self.new_obj.id,self.new_obj.name)
        md=ca.createModelAdmin(self.new_obj.id)
        s.register(m,md)
        ca.clearAndRload()
        pass
    def delete_models(self,queryset):
        n = queryset.count()
        if n:
            ca = categoryAdmin(ArticleType, Article)
            for obj in queryset:
                ca.unregister(obj.id)
            ca.clearAndRload()
        a = super(artTypeAdmin, self).delete_models(queryset)
        return a
xadmin.site.register(ArticleType,artTypeAdmin)


class categoryAdmin():
    def __init__(self, categoryModel, itemModel):
        self.catgModel = categoryModel
        self.itemModel = itemModel
        self.parent = self.getFK_name(self.catgModel,self.catgModel)
        self.foreign = self.getFK_name(self.itemModel,self.catgModel)
        self.list_display = [f.name for f in self.itemModel._meta.fields]
        self.catgs = self.catgModel.objects.filter(**{self.parent: None})

    def getFK_name(self,md,fkMd):
        for field in md._meta.fields:
            if isinstance(field, (models.ForeignKey, models.OneToOneField)) and issubclass(fkMd, field.rel.to):
                fk_name = field.name
        return fk_name
    def createModel(self, catgId, verbose):
        name="%s%s"%(self.catgModel.__name__,catgId)
        class Meta:
            proxy = True
            verbose_name_plural = verbose
            verbose_name = verbose
            ordering = ['display_sort']
        return type(name, (self.itemModel,), dict(__module__=__name__, Meta=Meta,app_label='miniSite'))
    def createModelAdmin(self, p):
        name="%s%sAdmin"%(self.catgModel.__name__,p)
        def queryset(inst):
            filterKey = "%s__%s_id" % (self.foreign, self.parent)
            return inst.model.objects.filter(**{filterKey: p})
        c=type(name, (ueditorAdmin,),
                    {"adminName": name,  "list_display": self.list_display,
                     "queryset": queryset})
        def get_form_helper(inst, *args, **kwargs):
            inst.form_obj.fields[self.foreign].queryset = self.catgModel.objects.filter(**{"%s_id"%self.parent:p})
            return super(c, inst).get_form_helper(*args, **kwargs)
        c.get_form_helper=get_form_helper
        return c
    def register(self):
        for catg in self.catgs:
            m = self.createModel(catg.id, catg.name)
            adm = self.createModelAdmin(catg.id)
            for rs in tuple(xadmin.site._registry):
                if m.__name__==rs.__name__:
                    xadmin.site.unregister(rs)
            xadmin.site.register(m, adm)
    def unregister(self,id):
        name="%s%s"%(self.catgModel.__name__,id)
        for rs in tuple(xadmin.site._registry):
            if name == rs.__name__:
                xadmin.site.unregister(rs)
    def clearAndRload(self):
        clear_url_caches()
        reload(import_module(settings.ROOT_URLCONF))




ca=categoryAdmin(ArticleType,Article)
ca.register()

posted on 2017-07-28 09:03  chevsea  阅读(843)  评论(0)    收藏  举报

导航