Skip to main content
 首页 » 编程设计

python之如何在 Django 中按父类别订购模型

2024年11月24日21java哥

我有一个模型“Category”,外键指向“parent_category”。 我如何在 Django 管理 ListView 中订购此模型,例如:

- 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”。

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', 
    ] 
 

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

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

请您参考如下方法:

对我有用的是向模型添加一个新字段“absolute_name”,该字段将自动填充 pre_save 信号。保存实例后,该字段将包含该实例的所有parent_categories 的名称,位于它自己的名称之前。最后,我只需要在这个字段上订购实例:

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