如何在Django中按父类别订购模型? [英] How do I order a model by parent category in django?

查看:60
本文介绍了如何在Django中按父类别订购模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模型"Category",其外键为"parent_category". 如何在Django管理列表视图中订购此模型,如:

I have a model "Category" with a ForeignKey to "parent_category". How can I order this model in the Django admin list view like:

- category 1
-- subcategory 1 of category 1
--- subsubcategory 1 of subcategory 1 of category 1
-- subcategory 2 of category 1
-- subcategory 3 of category 1
- category 2
-- subcategory 1 of category 2
-- subcategory 2 of category 2

我尝试了以下操作,但这不起作用.因此,我需要一些帮助来订购函数"get_relative_name".

I have tried the following but this won't work. So I need some help to order the function 'get_relative_name'.

class PrivateContentCategory(models.Model):
    name = models.CharField(
        max_length=250,
        verbose_name=_('Naam'),
    )
    slug = models.SlugField(
        verbose_name=_('Url'),
        blank=True,
    )
    parent_category = models.ForeignKey(
        'self',
        on_delete=models.SET_NULL,
        related_name='child_category_list',
        verbose_name=_('Hoofdcategorie'),
        blank=True,
        null=True,
    )

    def __str__(self):
        str = self.name
        parent_category_obj = self.parent_category
        while parent_category_obj is not None:
            str = parent_category_obj.name + ' --> ' + str
            parent_category_obj = parent_category_obj.parent_category
        return str

    def get_relative_name(self):
        str = self.name
        parent_category_obj = self.parent_category
        while parent_category_obj is not None:
            str = '--' + str
            parent_category_obj = parent_category_obj.parent_category
    get_relative_name.short_description = _('Naam')
    get_relative_name.admin_order_field = [
        'parent_category__parent_category',
        'name',
    ]

编辑!!! 父类别的名称不应与该类别一起显示.我这样写是为了显示如何订购模型.列表的显示将是:

EDIT!!! The names of the parent category should not be displayed with the category. I had written it like this to display how the model should be ordered. The display of the list will just be:

- OS
-- Windows
--- Windows 7
--- Windows 8
--- Windows 10
-- Mac
-- Linux
--- Debian
---- Ubuntu
--- Fedora
---- CentOS
---- Oracle Linux

推荐答案

对我有用的是在模型中添加一个新字段"absolute_name",该字段将使用pre_save信号自动填充.保存实例后,此字段将在实例本身名称之前包含该实例的所有parent_categories的名称.最后,我只需要在此字段上订购实例:

What worked for me was to add a new field "absolute_name" to the model which will be auto populated with a pre_save signal. After an instance is saved, this field will conain the names for all parent_categories of the instance before it own name. At last, I just needed to order the instance on this field:

class PrivateContentCategory(models.Model):
    name = models.CharField(
        max_length=250,
        verbose_name=_('Naam'),
    )
    slug = models.SlugField(
        verbose_name=_('Url'),
        blank=True,
    )
    parent_category = models.ForeignKey(
        'self',
        on_delete=models.SET_NULL,
        related_name='child_category_list',
        verbose_name=_('Hoofdcategorie'),
        blank=True,
        null=True,
    )
    absolute_name = models.TextField(
        verbose_name=_('Absolute naam'),
        blank=True,
    )

    def __str__(self):
        return self.absolute_name

    def get_relative_name(self):
        str = self.name
        parent_category_obj = self.parent_category
        while parent_category_obj is not None:
            str = '--' + str
            parent_category_obj = parent_category_obj.parent_category
        return str
    get_relative_name.short_description = _('Naam')
    get_relative_name.admin_order_field = [
        'absolute_name',
    ]

    class Meta:
        verbose_name = _('Privé inhoud categorie')
        verbose_name_plural = _('Privé inhoud categorieën')
        ordering = [
            'absolute_name',
        ]


@receiver(models.signals.pre_save, sender=PrivateContentCategory)
def pre_save_private_content_category_obj(sender, instance, **kwargs):
    # START Generate instance.absolute_name
    instance.absolute_name = instance.name
    parent_category_obj = instance.parent_category
    while parent_category_obj is not None:
        instance.absolute_name = parent_category_obj.name + ' --> ' + instance.absolute_name
        parent_category_obj = parent_category_obj.parent_category
    # END Generate instance.absolute_name

这篇关于如何在Django中按父类别订购模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆