在 Django 中动态地从对象 _meta 获取外键的详细名称
Get verbose name of foreign key from objects _meta dynamically in Django
为简单起见,使用如下模型:
class Plan(models.Model)
name = models.CharField(max_length=255, verbose_name="Phone Plan Name")
monthly_charge = models.FloatField()
class Company(models.Model):
name = models.CharField(max_length=255, verbose_name="Company Full Name")
phone_plan = models.ForeignKey(Plan)
class Client(models.Model):
name = models.CharField(max_length=255, verbose_name="Client Full Name")
company = models.ForeignKey(Company)
给定一个字符串,我想知道是否有一种简单的方法来检索模型属性的详细名称,即使该字符串遍历外键也是如此。
我知道我可以通过
获取 Client
属性的详细名称
Client._meta.get_field("name").verbose_name
这将导致 "Client Full Name"。
但是如果我有字符串 "company__phone_plan__name" 怎么办,我不能简单地使用
Client._meta.get_field("company__phone_plan__name").verbose_name
到达 "Phone Plan Name" 因为它产生错误。
这些字符串将是动态的,所以我想知道获得属性的正确详细名称的最简单方法是什么,即使它遍历模型?
这个特殊案例使用的是 Django 1.11
这不是很好的答案,但如果你需要你想要的,你可以使用这个功能:
def get_verbose_name(model, string):
fields = string.split('__')
for field_name in fields[:-1]:
field = model._meta.get_field(field_name)
if field.many_to_one:
model = field.foreign_related_fields[0].model
elif field.many_to_many or field.one_to_one or field.one_to_many:
model = field.related_model
else:
raise ValueError('incorrect string')
return model._meta.get_field(fields[-1]).verbose_name
此函数获取模型名称和字符串以及 return 详细名称
你可以这样使用它:
get_verbose_name(Client, 'company__phone_plan__name')
如果您正在使用模型实例,那么您可以试试这个:
c = Client.objects.first()
# c._meta.get_field('company').verbose_name
# c.company._meta.get_field('phone_plan').verbose_name
c.company.phone_plan._meta.get_field('name').verbose_name
如果您只使用 类,那么它会更复杂:
field_company = Client._meta.get_field('company')
field_phone_plan = field_company.rel.to._meta.get_field('phone_plan')
field_name = field_phone_plan.rel.to._meta.get_field('name')
field_name.verbose_name
# or one long line
s = Client._meta.get_field('company') \
.rel.to._meta.get_field('phone_plan') \
.rel.to._meta.get_field('name') \
.verbose_name
编辑:
用户@AndreyBerenda 指出第二个选项在 Django 2.1
中对他不起作用;我只在问题中指定的 1.11
中进行了测试。
为简单起见,使用如下模型:
class Plan(models.Model)
name = models.CharField(max_length=255, verbose_name="Phone Plan Name")
monthly_charge = models.FloatField()
class Company(models.Model):
name = models.CharField(max_length=255, verbose_name="Company Full Name")
phone_plan = models.ForeignKey(Plan)
class Client(models.Model):
name = models.CharField(max_length=255, verbose_name="Client Full Name")
company = models.ForeignKey(Company)
给定一个字符串,我想知道是否有一种简单的方法来检索模型属性的详细名称,即使该字符串遍历外键也是如此。
我知道我可以通过
获取Client
属性的详细名称
Client._meta.get_field("name").verbose_name
这将导致 "Client Full Name"。
但是如果我有字符串 "company__phone_plan__name" 怎么办,我不能简单地使用
Client._meta.get_field("company__phone_plan__name").verbose_name
到达 "Phone Plan Name" 因为它产生错误。
这些字符串将是动态的,所以我想知道获得属性的正确详细名称的最简单方法是什么,即使它遍历模型?
这个特殊案例使用的是 Django 1.11
这不是很好的答案,但如果你需要你想要的,你可以使用这个功能:
def get_verbose_name(model, string):
fields = string.split('__')
for field_name in fields[:-1]:
field = model._meta.get_field(field_name)
if field.many_to_one:
model = field.foreign_related_fields[0].model
elif field.many_to_many or field.one_to_one or field.one_to_many:
model = field.related_model
else:
raise ValueError('incorrect string')
return model._meta.get_field(fields[-1]).verbose_name
此函数获取模型名称和字符串以及 return 详细名称
你可以这样使用它:
get_verbose_name(Client, 'company__phone_plan__name')
如果您正在使用模型实例,那么您可以试试这个:
c = Client.objects.first()
# c._meta.get_field('company').verbose_name
# c.company._meta.get_field('phone_plan').verbose_name
c.company.phone_plan._meta.get_field('name').verbose_name
如果您只使用 类,那么它会更复杂:
field_company = Client._meta.get_field('company')
field_phone_plan = field_company.rel.to._meta.get_field('phone_plan')
field_name = field_phone_plan.rel.to._meta.get_field('name')
field_name.verbose_name
# or one long line
s = Client._meta.get_field('company') \
.rel.to._meta.get_field('phone_plan') \
.rel.to._meta.get_field('name') \
.verbose_name
编辑:
用户@AndreyBerenda 指出第二个选项在 Django 2.1
中对他不起作用;我只在问题中指定的 1.11
中进行了测试。