¿Puedes darle a una aplicación Django un nombre detallado para usar en todo el administrador?

140

De la misma manera que puede dar nombres detallados de campos y modelos que aparecen en el administrador de Django, ¿puede darle a una aplicación un nombre personalizado?

rmh
fuente
44
Este ticket abordaría esto: code.djangoproject.com/ticket/3591 . Desafortunadamente, no parece que se integraría en Django en el corto plazo ...
Benjamin Wohlwend
10
A partir de Django 1.7, esto ahora es posible fuera de la caja - ver docs.djangoproject.com/en/1.7/ref/applications/…
rhunwicks

Respuestas:

182

Django 1.8+

Según los 1.8 documentos (y los documentos actuales ),

Las nuevas aplicaciones deben evitarse default_app_config. En su lugar, deberían requerir que la ruta punteada a la AppConfigsubclase apropiada se configure explícitamente en INSTALLED_APPS.

Ejemplo:

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

Luego modifique su AppConfigcomo se enumera a continuación.

Django 1.7

Como lo indica el comentario de rhunwicks a OP, esto es posible desde el primer momento desde Django 1.7

Tomado de los documentos :

# in yourapp/apps.py
from django.apps import AppConfig

class YourAppConfig(AppConfig):
    name = 'yourapp'
    verbose_name = 'Fancy Title'

luego establezca la default_app_configvariable enYourAppConfig

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

Antes de Django 1.7

Puede darle a su aplicación un nombre personalizado definiendo app_label en la definición de su modelo. Pero a medida que django construye la página de administración, los códigos hash aparecerán según su etiqueta de aplicación, por lo que si desea que aparezcan en una aplicación, debe definir este nombre en todos los modelos de su aplicación.

class MyModel(models.Model):
        pass
    class Meta:
        app_label = 'My APP name'
Frost.baka
fuente
12
Estaba teniendo problemas con esto en el administrador. Tanto depende de la etiqueta de aplicación que cuando comencé a cambiar el nombre, rompió esas cosas.
Joe J
Lo sé, terminé escribiendo un templatag que tenía un dict con app_url: enlace de app_name.
Frost.baka
58
Tenga en cuenta que esto NO es lo mismo que un nombre detallado, en el sentido de que solo afecta lo que se muestra al usuario. Es la cadena literal utilizada para nombrar la tabla en la base de datos, que requiere una migración de esquema si está cambiando un modelo existente.
Cerin
66
No creo que esta sea una buena solución. Tiene muchos otros efectos secundarios que no son estéticos.
David Sanders
Esta respuesta popular recomienda usar un hack / solución que era necesaria antes de Django 1.7. Si está utilizando 1.7 o superior, use un archivo apps.py como se recomienda a continuación por iMaGiNiX.
Shacker 02 de
38

Como lo indica el comentario de rhunwicks a OP, esto es posible desde el primer momento desde Django 1.7

Tomado de los documentos :

# in yourapp/apps.py
from django.apps import AppConfig

class YourAppConfig(AppConfig):
    name = 'yourapp'
    verbose_name = 'Fancy Title'

luego establezca la default_app_configvariable enYourAppConfig

# in yourapp/__init__.py
default_app_config = 'yourapp.apps.YourAppConfig'
r --------- k
fuente
Funciona bien, pero el código en el archivo init .py no es necesario si instala la aplicación como un ejemplo de recomendación de Django en INTALLED_APPS: 'App_name.apps.AppnameConfig'
Roberth Solís
31

Si tiene más de un modelo en la aplicación, simplemente cree un modelo con la información Meta y cree subclases de esa clase para todos sus modelos.

class MyAppModel(models.Model):
    class Meta:
        app_label = 'My App Label'
        abstract = True

class Category(MyAppModel):
     name = models.CharField(max_length=50)
man2xxl
fuente
12

Dales una propiedad verbose_name.

No te hagas ilusiones. También deberá copiar la vista de índice de django.contrib.admin.sites en su propia vista ProjectAdminSite e incluirla en su propia instancia de administrador personalizada:

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

admin.site = ProjectAdminSite()

luego modifique la vista copiada para que use su propiedad verbose_name como etiqueta para la aplicación.

Lo hice agregando algo como esto a la vista copiada:

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

Mientras modifica la vista de índice, ¿por qué no agrega también una propiedad de 'pedido'?

Andy Baker
fuente
12

Bueno, comencé una aplicación llamada todo y ahora he decidido que quiero que se llame Tareas . El problema es que ya tengo datos dentro de mi tabla, por lo que mi solución fue la siguiente. Colocado en el models.py:

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

Espero eso ayude.

Darren
fuente
7

Para Django 1.4 (aún no lanzado, pero el tronco es bastante estable), puede usar el siguiente método. Se basa en el hecho de que AdminSite ahora devuelve un TemplateResponse, que puede modificar antes de que se procese.

Aquí, hacemos un pequeño parche de mono para insertar nuestro comportamiento, lo que puede evitarse si usa una subclase de AdminSite personalizada.

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)

Esto corrige el índice y las vistas app_index. No repara las migas de pan en todas las demás vistas de administrador.

Spookylukey
fuente
7

Primero debe crear un apps.pyarchivo como este en su carpeta de aplicaciones:

# appName/apps.py

# -*- coding: utf-8 -*-             
from django.apps import AppConfig

class AppNameConfig(AppConfig):
    name = 'appName'
    verbose_name = "app Custom Name"

Para cargar esta subclase de AppConfig de forma predeterminada:

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

Es la mejor manera de hacerlo. probado en Django 1.7

Mi nombre de aplicación personalizado

Para la persona que tuvo problemas con el español

Este código habilita la compatibilidad utf-8 en scripts python2

# -*- coding: utf-8 -*-
iMaGiNiX
fuente
Solo unas pocas notas secundarias pedantes: crear un archivo llamado apps.pyno es obligatorio. Cualquier nombre está bien (pero debe referirse a él en __init__.py). Como ya se dijo en otros comentarios, este código funciona para django> = 1.7 ( docs.djangoproject.com/en/1.7/ref/applications/… ).
Furins 02 de
Funciona bien, pero el código en el archivo init .py no es necesario si instala la aplicación como un ejemplo de recomendación de Django en INTALLED_APPS: 'App_name.apps.AppnameConfig'
Roberth Solís
6

No, pero puede copiar la plantilla de administrador y definir el nombre de la aplicación allí.

temoto
fuente
3

Hay un truco que se puede hacer que no requiere ninguna migración. Tomado del blog de Ionel y el crédito va para él: http://blog.ionelmc.ro/2011/06/24/custom-app-names-in-the-django-admin/

También hay un boleto para esto que debe corregirse en Django 1.7 https://code.djangoproject.com/ticket/3591

"" "

Supongamos que tiene un modelo como este:

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

Tiene verbose_name, sin embargo, también desea personalizar app_label para una visualización diferente en admin. Desafortunadamente, tener una cadena arbitraria (con espacios) no funciona y no se puede mostrar de todos modos.

Resulta que el administrador usa app_label. title () para mostrar para que podamos hacer una pequeña subclase de hack: str con el método de título anulado:

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

Ahora podemos tener el modelo así:

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'

y el administrador mostrará "El cuadro de cosas" como el nombre de la aplicación.

"" "

odedfos
fuente
2

Si ya tiene tablas existentes que usan el nombre de la aplicación anterior y no desea migrarlas, simplemente configure app_label en un proxy del modelo original.

class MyOldModel(models.Model):
    pass

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

Entonces solo tienes que cambiar esto en tu admin.py:

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

Tenga en cuenta que la url será / admin / NewAPPname / mynewmodel /, por lo que es posible que desee asegurarse de que el nombre de la clase para el nuevo modelo se parezca lo más posible al modelo anterior.

egrubbs
fuente
1

Bueno, esto funciona para mi. En la app.py usa esto:

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

En setting.py agregue el nombre de la aplicación y el nombre de la clase presente en el archivo app.py en la carpeta de la aplicación

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

]

Akash Elhance
fuente
0

El siguiente código plug-and-play funciona perfectamente desde entonces Django 1.7. Todo lo que tiene que hacer es copiar el siguiente código en el __init__.pyarchivo de la aplicación específica y cambiar el VERBOSE_APP_NAMEparámetro.

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'

Si usa esto para múltiples aplicaciones, debe descomponer la get_current_app_namefunción en un archivo auxiliar.

Vlad Schnakovszki
fuente