如何在Django Serializer中获取模型的verbose name?
解决方案
一、将模型verbose_name作为Serializer输出键的实现
要把模型的verbose_name(或verbose_name_plural)作为Serializer输出的键,重写Serializer的to_representation方法即可实现自定义键名:
from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from .models import ProductCategory, DeviceTypeCategory, DeviceBrandCategory, PartTypeCategory class ProductCategorySerializer(serializers.ModelSerializer): device_types = serializers.StringRelatedField(many=True) device_brands = serializers.StringRelatedField(many=True) part_types = serializers.StringRelatedField(many=True) class Meta: model = ProductCategory fields = ('name', 'device_types', 'device_brands', 'part_types') def to_representation(self, instance): data = super().to_representation(instance) # 替换原有键为对应模型的verbose_name_plural data[DeviceTypeCategory._meta.verbose_name_plural] = data.pop('device_types') data[DeviceBrandCategory._meta.verbose_name_plural] = data.pop('device_brands') data[PartTypeCategory._meta.verbose_name_plural] = data.pop('part_types') return data
- 如果想用单数verbose_name,把代码里的
verbose_name_plural换成verbose_name即可 - 因为你用了
_()翻译函数,输出的名称会自动适配当前语言环境
二、多分类场景的模型设计思路
你提到需要产品属于多个子分类,django-mptt的树形结构不适合这种场景,另外你当前的模型设计存在冗余问题:子类继承ProductCategory后,Django会自动生成productcategory_ptr一对一关联字段,你额外添加的product_category外键完全多余,建议删除或重新设计。下面是几种适合多分类的方案:
1. 多对多关联的层级分类模型
适合需要层级结构+多分类关联的场景:
from django.utils import timezone class Category(models.Model): name = models.CharField(max_length=150, unique=True) parent = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True, related_name='children') created_at = models.DateTimeField(default=timezone.now) modified_at = models.DateTimeField(default=timezone.now) def __str__(self): return self.name # 示例产品模型 class Product(models.Model): name = models.CharField(max_length=200) categories = models.ManyToManyField(Category, related_name='products') # 其他业务字段...
- 一个产品可以关联任意数量的分类
- 分类支持父子层级,可实现多级分类
2. 分类类型+多对多关联
如果需要区分不同类别的分类(如设备类型、品牌、部件类型),可以单独设计分类类型:
class CategoryType(models.Model): name = models.CharField(max_length=100, unique=True) verbose_name = models.CharField(max_length=100) # 自定义分类类型的显示名称 class Category(models.Model): name = models.CharField(max_length=150, unique=True) type = models.ForeignKey(CategoryType, on_delete=models.CASCADE, related_name='categories') parent = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True, related_name='children') created_at = models.DateTimeField(default=timezone.now) modified_at = models.DateTimeField(default=timezone.now) class Product(models.Model): name = models.CharField(max_length=200) categories = models.ManyToManyField(Category, related_name='products')
- 通过CategoryType区分不同类别的分类,便于管理
- 同样支持产品关联多分类、分类层级结构
3. 标签式分类(django-taggit)
如果不需要严格的层级结构,只是简单的多标签关联,推荐使用django-taggit:
from taggit.managers import TaggableManager class Product(models.Model): name = models.CharField(max_length=200) tags = TaggableManager() # 直接使用自带的标签管理器
- 开箱即用,支持多标签关联、标签搜索等功能
- 适合无层级的灵活分类场景
内容的提问来源于stack exchange,提问作者aboka
相关产品推荐
相关产品推荐

