给出一个名为 BlogPost
的Django模型。首先,它的编码没有Meta.verbose_name
。在./manage.py syncdb
时间,会自动创建名为“博客帖子”的ContentType
。在稍后的某个时间点,会添加“博客帖子”Meta.verbose_name
。
现在存在差异:ContentType
被称为“博客帖子”,而模型的详细名称为“博客帖子”,这种差异在使用通用关系的任何框架中显示,例如在评论'管理员。我想通过更改ContentType
的名称来纠正这种情况,但是,我不想手动(出于显而易见的原因)或通过迁移(因为我不迁移任何其他内容) ,Meta.verbose_name
只是代码更改。
在ContentType
更改后,您如何更新Meta.verbose_name
的名称?
答案 0 :(得分:10)
回答自己的问题:我设法通过一个小的post_migrate
信号来做到这一点。如果您不使用South,则可能完全可以以相同的方式使用post_syncdb
信号。欢迎对此代码发表任何评论。
from django.contrib.contenttypes.models import ContentType
from django.utils.functional import Promise
from south.signals import post_migrate
# or if using django >=1.7 migrations:
# from django.db.models.signals import post_migrate
def update_contenttypes_names(**kwargs):
for c in ContentType.objects.all():
cl = c.model_class()
# Promises classes are from translated, mostly django-internal models. ignore them.
if cl and not isinstance(cl._meta.verbose_name, Promise):
new_name = cl._meta.verbose_name
if c.name != new_name:
print u"Updating ContentType's name: '%s' -> '%s'" % (c.name, new_name)
c.name = new_name
c.save()
post_migrate.connect(update_contenttypes_names, dispatch_uid="update_contenttypes")
答案 1 :(得分:1)
另一种方法是覆盖ContentType.__str__
方法,如下所示:
def __str__(self):
# self.name is deprecated in favor of using model's verbose_name, which
# can be translated. Formal deprecation is delayed until we have DB
# migration to be able to remove the field from the database along with
# the attribute.
#
# We return self.name only when users have changed its value from the
# initial verbose_name_raw and might rely on it.
model = self.model_class()
if not model or self.name != model._meta.verbose_name_raw:
return self.name
else:
return force_unicode(model._meta.verbose_name)
因此,如果您不需要某种向后兼容性,则可以重写它:
from django.contrib.contenttypes.models import ContentType
from django.utils.encoding import force_unicode
def contenttype_as_str(self):
return force_unicode(self.model_class()._meta.verbose_name)
ContentType.__str__ = contenttype_as_str
这有点棘手,但我相信它更直接。请注意,由于使用了Django 1.4.1 force_text
而不是force_unicode
。