Você pode dar a um aplicativo Django um nome detalhado para uso em todo o administrador?

140

Da mesma maneira que você pode dar nomes detalhados aos campos e modelos que aparecem no administrador do Django, você pode dar um nome personalizado a um aplicativo?

rmh
fonte
4
Este ticket abordaria o seguinte: code.djangoproject.com/ticket/3591 . Infelizmente, não parece como seria integrado no Django tão cedo ...
Benjamin Wohlwend
10
A partir de Django 1.7 é agora possível fora da caixa - ver docs.djangoproject.com/en/1.7/ref/applications/...
rhunwicks

Respostas:

182

Django 1.8+

De acordo com os 1,8 documentos (e documentos atuais ),

Novas aplicações devem evitar default_app_config. Em vez disso, eles devem exigir que o caminho pontilhado da AppConfigsubclasse apropriada seja configurado explicitamente INSTALLED_APPS.

Exemplo:

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

Altere o seu AppConfigconforme listado abaixo.

Django 1.7

Como afirmado pelo comentário de rhunwicks ao OP, isso agora é possível desde o Django 1.7

Retirado dos documentos :

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

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

defina a default_app_configvariável comoYourAppConfig

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

Antes do Django 1.7

Você pode atribuir um nome personalizado ao seu aplicativo definindo app_label na definição do seu modelo. Mas, como o django constrói a página de administração, ele cria modelos de hash com o app_label; portanto, se você deseja que eles apareçam em um aplicativo, é necessário definir esse nome em todos os modelos do aplicativo.

class MyModel(models.Model):
        pass
    class Meta:
        app_label = 'My APP name'
Frost.baka
fonte
12
Eu estava tendo problemas com isso no administrador. Depende tanto do app_label que, quando comecei a mudar o nome, ele quebrou essas coisas.
Joe J
Eu sei, acabei escrevendo um modelo de etiqueta que tinha um ditado com a ligação app_url: app_name.
Frost.baka
58
Observe que NÃO é o mesmo que um nome detalhado, no sentido de afetar apenas o que é mostrado ao usuário. É a string literal usada para nomear a tabela no banco de dados, que requer uma migração de esquema se você estiver alterando um modelo existente.
Cerin
6
Não acho que seja uma boa solução. Tem muitos outros efeitos colaterais que não são estéticos.
David Sanders
Esta resposta popular recomenda o uso de um hack / solução alternativa necessária antes do Django 1.7. Se você estiver usando a versão 1.7 ou superior, use um arquivo apps.py conforme recomendado abaixo pelo iMaGiNiX.
#
38

Como afirmado pelo comentário de rhunwicks ao OP, isso agora é possível desde o Django 1.7

Retirado dos documentos :

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

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

defina a default_app_configvariável comoYourAppConfig

# in yourapp/__init__.py
default_app_config = 'yourapp.apps.YourAppConfig'
r --------- k
fonte
É woks bem, mas o código de inicialização arquivo .py não é necessário se você instalar o aplicativo como um exemplo recomendação Django em INTALLED_APPS: 'App_name.apps.AppnameConfig'
Roberth Solís
31

Se você tiver mais de um modelo no aplicativo, crie um modelo com as informações Meta e crie subclasses dessa classe para todos os seus modelos.

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

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

Dê a eles uma propriedade verbose_name.

Não tenha muitas esperanças. Você também precisará copiar a visualização de índice de django.contrib.admin.sites para sua própria visualização do ProjectAdminSite e incluí-la em sua própria instância de administrador personalizada:

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

admin.site = ProjectAdminSite()

em seguida, ajuste a visualização copiada para que ela use sua propriedade verbose_name como o rótulo do aplicativo.

Fiz isso adicionando algo parecido com isto à exibição copiada:

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

Enquanto você ajusta a exibição do índice, por que não adicionar uma propriedade 'order' também.

Andy Baker
fonte
12

Bem, eu iniciei um aplicativo chamado todo e agora decidi que quero que ele seja chamado de Tarefas . O problema é que eu já tenho dados em minha tabela, portanto, minha solução foi a seguinte. Colocado no models.py:

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

Espero que ajude.

darren
fonte
7

Para o Django 1.4 (ainda não lançado, mas o tronco é bastante estável), você pode usar o seguinte método. Ele se baseia no fato de que o AdminSite agora retorna um TemplateResponse, que você pode alterar antes de ser renderizado.

Aqui, fazemos um pequeno patch de macaco para inserir nosso comportamento, o que pode ser evitado se você usar uma subclasse 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)

Isso corrige o índice e as visualizações app_index. Ele não corrige as migalhas de pão em todas as outras visualizações de administrador.

spookylukey
fonte
7

Primeiro, você precisa criar um apps.pyarquivo como este na sua pasta de aplicativos:

# appName/apps.py

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

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

Para carregar esta subclasse AppConfig por padrão:

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

É a melhor maneira de fazer. testado no Django 1.7

Meu nome do aplicativo personalizado

Para a pessoa que teve problemas com o espanhol

Este código habilita a compatibilidade utf-8 em scripts python2

# -*- coding: utf-8 -*-
iMaGiNiX
fonte
Apenas algumas notas secundárias pedantes: criar um arquivo chamado apps.pynão é obrigatório. Qualquer nome é bom (mas você deve fazer referência a ele __init__.py). Como já foi dito em outros comentários, esse código funciona para django> = 1.7 ( docs.djangoproject.com/en/1.7/ref/applications/… ).
Furin
É woks bem, mas o código de inicialização arquivo .py não é necessário se você instalar o aplicativo como um exemplo recomendação Django em INTALLED_APPS: 'App_name.apps.AppnameConfig'
Roberth Solís
6

Não, mas você pode copiar o modelo de administrador e definir o nome do aplicativo.

temoto
fonte
3

Existe um hack que pode ser feito que não requer nenhuma migração. Retirado do blog de Ionel, o crédito é para ele: http://blog.ionelmc.ro/2011/06/24/custom-app-names-in-the-django-admin/

Também existe um ticket para isso que deve ser corrigido no Django 1.7 https://code.djangoproject.com/ticket/3591

"" "

Suponha que você tenha um modelo como este:

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

Você possui verbose_name, mas também deseja personalizar o app_label para exibição diferente em admin. Infelizmente, ter uma sequência arbitrária (com espaços) não funciona e não é para exibição de qualquer maneira.

Acontece que o administrador usa app_label. title () para exibição, para que possamos criar uma subclasse hack: str com o método title:

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

Agora podemos ter o modelo assim:

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'

e o administrador mostrará "A caixa de itens" como o nome do aplicativo.

"" "

odedfos
fonte
2

Se você já possui tabelas usando o nome do aplicativo antigo e não deseja migrá-las, basta definir o app_label em um proxy do 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

Então você só precisa mudar isso no seu admin.py:

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

Esteja ciente de que o URL será / admin / NewAPPname / mynewmodel /, portanto, você pode querer apenas garantir que o nome da classe para o novo modelo seja o mais próximo possível do modelo antigo.

egrubbs
fonte
1

Bem, isso funciona para mim. No app.py, use isto:

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

Em setting.py, adicione o nome do aplicativo e o nome da classe presente no arquivo app.py na pasta do aplicativo

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
fonte
0

O seguinte código plug-and-play funciona perfeitamente desde então Django 1.7. Tudo o que você precisa fazer é copiar o código abaixo no __init__.pyarquivo do aplicativo específico e alterar o 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'

Se você usar isso para vários aplicativos, você deve fatorar a get_current_app_namefunção em um arquivo auxiliar.

Vlad Schnakovszki
fonte