【问题标题】:Can you give a Django app a verbose name for use throughout the admin?你能给一个 Django 应用程序一个详细的名称以供整个管理员使用吗?
【发布时间】:2010-10-11 08:58:25
【问题描述】:

就像您可以为出现在 Django 管理中的字段和模型提供详细名称一样,您可以为应用程序指定一个自定义名称吗?

【问题讨论】:

标签: python django


【解决方案1】:

否,但您可以复制管理模板并在那里定义应用名称。

【讨论】:

    【解决方案2】:

    给他们一个 verbose_name 属性。

    不要抱太大希望。您还需要将 django.contrib.admin.sites 中的索引视图复制到您自己的 ProjectAdminSite 视图中,并将其包含在您自己的自定义管理实例中:

    class ProjectAdminSite(AdminSite):
        def index(self, request, extra_context=None):
            copied stuff here...
    
    admin.site = ProjectAdminSite()
    

    然后调整复制的视图,使其使用您的 verbose_name 属性作为应用的标签。

    我通过在复制的视图中添加一些类似的东西来做到这一点:

            try:
                app_name = model_admin.verbose_name
            except AttributeError:
                app_name = app_label
    

    在调整索引视图时,为什么不也添加一个“订单”属性。

    【讨论】:

      【解决方案3】:

      Django 1.8+

      根据1.8 docs(和current docs),

      新应用程序应避免使用default_app_config。相反,他们应该要求在INSTALLED_APPS 中显式配置相应AppConfig 子类的虚线路径。

      例子:

      INSTALLED_APPS = [
          # ...snip...
          'yourapp.apps.YourAppConfig',
      ]
      

      然后更改您的AppConfig,如下所示。

      Django 1.7

      正如 rhunwicks 对 OP 的评论所述,自 Django 1.7 以来,这现在可以开箱即用

      取自docs

      # in yourapp/apps.py
      from django.apps import AppConfig
      
      class YourAppConfig(AppConfig):
          name = 'yourapp'
          verbose_name = 'Fancy Title'
      

      然后将default_app_config 变量设置为YourAppConfig

      # in yourapp/__init__.py
      default_app_config = 'yourapp.apps.YourAppConfig'
      

      Django 1.7 之前的版本

      您可以通过在模型定义中定义 app_label 来为您的应用程序指定一个自定义名称。但是当 django 构建管理页面时,它会通过它们的 app_label 对模型进行哈希处理,所以如果你希望它们出现在一个应用程序中,你必须在应用程序的所有模型中定义这个名称。

      class MyModel(models.Model):
              pass
          class Meta:
              app_label = 'My APP name'
      

      【讨论】:

      • 我在管理员中遇到了这个问题。很大程度上取决于 app_label,以至于当我开始更改名称时,它破坏了那些东西。
      • 我知道,我最终写了一个模板标签,它有一个带有 app_url:app_name 绑定的字典。
      • 请注意,这与详细名称不同,因为它只影响向用户显示的内容。它是用于命名数据​​库中表的文字字符串,如果您要更改现有模型,则需要进行架构迁移。
      • 我认为这不是一个好的解决方案。它有太多其他不美观的副作用。
      • 这个流行的答案建议使用 Django 1.7 之前需要的 hack/workaround。如果您使用的是 1.7 或更高版本,请使用 iMaGiNiX 下面推荐的 apps.py 文件。
      【解决方案4】:

      我创建了一个名为 todo 的应用程序,现在我决定将它命名为 Tasks。问题是我的表中已经有数据,所以我的工作如下。放入models.py:

          class Meta:
             app_label = 'Tasks'
             db_table = 'mytodo_todo'
      

      希望对你有帮助。

      【讨论】:

        【解决方案5】:

        如果您的应用中有多个模型,只需使用元信息创建一个模型,然后为您的所有模型创建该类的子类。

        class MyAppModel(models.Model):
            class Meta:
                app_label = 'My App Label'
                abstract = True
        
        class Category(MyAppModel):
             name = models.CharField(max_length=50)
        

        【讨论】:

          【解决方案6】:

          对于 Django 1.4(尚未发布,但 trunk 相当稳定),您可以使用以下方法。它依赖于 AdminSite 现在返回一个 TemplateResponse 的事实,您可以在呈现之前对其进行更改。

          在这里,我们做了一点猴子补丁来插入我们的行为,如果您使用自定义 AdminSite 子类,可以避免这种情况。

          from functools import wraps
          def rename_app_list(func):
              m = {'Sites': 'Web sites',
                   'Your_app_label': 'Nicer app label',
              }
          
              @wraps(func)
              def _wrapper(*args, **kwargs):
                  response = func(*args, **kwargs)
                  app_list = response.context_data.get('app_list')
          
                  if app_list is not None:
                      for a in app_list:
                          name = a['name']
                          a['name'] = m.get(name, name)
                  title = response.context_data.get('title')
                  if title is not None:
                      app_label = title.split(' ')[0]
                      if app_label in m:
                          response.context_data['title'] = "%s administration" % m[app_label]
                  return response
              return _wrapper
          
          admin.site.__class__.index = rename_app_list(admin.site.__class__.index)
          admin.site.__class__.app_index = rename_app_list(admin.site.__class__.app_index)
          

          这修复了索引和 app_index 视图。它不会修复所有其他管理视图中的面包屑。

          【讨论】:

            【解决方案7】:

            如果您已经有使用旧应用名称的现有表,并且您不想迁移它们,那么只需在原始模型的代理上设置 app_label。

            class MyOldModel(models.Model):
                pass
            
            class MyNewModel(MyOldModel):
                class Meta:
                    proxy = True
                    app_label = 'New APP name'
                    verbose_name = MyOldModel._meta.verbose_name
            

            然后你只需要在你的 admin.py 中改变它:

            #admin.site.register(MyOldModel, MyOldModelAdmin)
            admin.site.register(MyNewModel, MyOldModelAdmin)
            

            请注意,该 url 将是 /admin/NewAPPname/mynewmodel/,因此您可能只想确保新模型的类名看起来尽可能接近旧模型。

            【讨论】:

              【解决方案8】:

              有一种无需任何迁移即可完成的 hack。 摘自 Ionel 的博客,感谢他:http://blog.ionelmc.ro/2011/06/24/custom-app-names-in-the-django-admin/

              还有一张应该在 Django 1.7 https://code.djangoproject.com/ticket/3591 中修复的票

              """

              假设你有一个这样的模型:

              class Stuff(models.Model):
                  class Meta:
                      verbose_name = u'The stuff'
                      verbose_name_plural = u'The bunch of stuff'
              

              您有verbose_name,但是您也想自定义app_label 以在管理员中进行不同的显示。不幸的是,有一些任意字符串(带空格)是行不通的,而且它也不是用来显示的。

              原来管理员使用 app_label。 title() 用于显示,所以我们可以做一个小技巧:str subclass with overriden title method:

              class string_with_title(str):
                  def __new__(cls, value, title):
                      instance = str.__new__(cls, value)
                      instance._title = title
                      return instance
              
                  def title(self):
                      return self._title
              
                  __copy__ = lambda self: self
                  __deepcopy__ = lambda self, memodict: self
              

              现在我们可以有这样的模型:

              class Stuff(models.Model):
                  class Meta:
                      app_label = string_with_title("stuffapp", "The stuff box")
                      # 'stuffapp' is the name of the django app
                      verbose_name = 'The stuff'
                      verbose_name_plural = 'The bunch of stuff'
              

              管理员将显示“The stuff box”作为应用名称。

              """

              【讨论】:

                【解决方案9】:

                首先,您需要在您的应用文件夹中创建一个像这样的apps.py 文件:

                # appName/apps.py
                
                # -*- coding: utf-8 -*-             
                from django.apps import AppConfig
                
                class AppNameConfig(AppConfig):
                    name = 'appName'
                    verbose_name = "app Custom Name"
                

                默认加载这个 AppConfig 子类:

                # appName/__init__.py
                default_app_config = 'appName.apps.AppNameConfig'
                

                是最好的办法。在 Django 1.7 上测试

                对于西班牙语有问题的人

                此代码在 python2 脚本上启用 utf-8 兼容性

                # -*- coding: utf-8 -*-
                

                【讨论】:

                • 只是一些迂腐的旁注:创建一个名为 apps.py 的文件不是强制性的。任何名称都可以(但您必须在 __init__.py 中引用它)。如其他 cmets 所述,此代码适用于 django >=1.7 (docs.djangoproject.com/en/1.7/ref/applications/…)。
                • 运行良好,但如果您将应用程序安装为 INTALLED_APPS 中的 Django 推荐示例,则不需要 init.py 文件中的代码:'App_name.apps.AppnameConfig'
                【解决方案10】:

                正如 rhunwicks 对 OP 的评论所述,自 Django 1.7 以来,这现在可以开箱即用了

                取自docs

                # in yourapp/apps.py
                from django.apps import AppConfig
                
                class YourAppConfig(AppConfig):
                    name = 'yourapp'
                    verbose_name = 'Fancy Title'
                

                然后将default_app_config 变量设置为YourAppConfig

                # in yourapp/__init__.py
                default_app_config = 'yourapp.apps.YourAppConfig'
                

                【讨论】:

                • 运行良好,但如果您将应用程序安装为 INTALLED_APPS 中的 Django 推荐示例,则不需要 init.py 文件中的代码:'App_name.apps.AppnameConfig'
                • 这是正确的答案,但对于 Django 3.x,您不需要更改 __init__
                【解决方案11】:

                Django 1.7 以来,以下即插即用的代码可以完美运行。您只需将以下代码复制到特定应用的__init__.py 文件中并更改VERBOSE_APP_NAME 参数即可。

                from os import path
                from django.apps import AppConfig
                
                VERBOSE_APP_NAME = "YOUR VERBOSE APP NAME HERE"
                
                
                def get_current_app_name(file):
                    return path.dirname(file).replace('\\', '/').split('/')[-1]
                
                
                class AppVerboseNameConfig(AppConfig):
                    name = get_current_app_name(__file__)
                    verbose_name = VERBOSE_APP_NAME
                
                
                default_app_config = get_current_app_name(__file__) + '.__init__.AppVerboseNameConfig'
                

                如果您将它用于多个应用程序,则应将 get_current_app_name 函数分解为帮助文件。

                【讨论】:

                  【解决方案12】:

                  嗯,这对我有用。在 app.py 中使用:

                  class MainConfig(AppConfig):
                      name = 'main'
                      verbose_name="Fancy Title"
                  

                  在 setting.py 中添加 App 的名称和 App 文件夹中 app.py 文件中的类名

                  INSTALLED_APPS = [
                      'main.apps.MainConfig',
                      'django.contrib.admin',
                      'django.contrib.auth',
                      'django.contrib.contenttypes',
                      'django.contrib.sessions',
                      'django.contrib.messages',
                      'django.contrib.staticfiles',
                  

                  ]

                  【讨论】:

                    【解决方案13】:

                    这很简单,只需在您的 appName/apps 上添加如下内容

                    class AppNameConfig(AppConfig):
                        default_auto_field = 'default Django'
                        name = 'AppName'
                        verbose_name = 'Name you Want'
                    

                    【讨论】:

                      【解决方案14】:

                      2021 年更新(Django 3.2):

                      在您应用的 app.py 文件中,您可以找到 AppClientsConfig 类。在里面你可以找到 name 属性。除非你真的需要,否则不要更改它(然后你还需要更改 settings.py 文件中的应用程序注册表......等等)。

                      改为向类添加一个属性,像这样

                      verbose_name = "The Name You Like"
                      

                      这应该可以解决问题。请随时在official Django documentation page 上阅读更多相关信息。

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2013-03-19
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多