Pouvez-vous donner à une application Django un nom détaillé à utiliser dans tout l'administrateur?

140

De la même manière que vous pouvez donner aux champs et aux modèles des noms détaillés qui apparaissent dans l'admin Django, pouvez-vous donner un nom personnalisé à une application?

rmh
la source
4
Ce ticket adresserait ceci: code.djangoproject.com/ticket/3591 . Malheureusement, cela ne semble pas être intégré à Django de si tôt ...
Benjamin Wohlwend
10
À partir de Django 1.7, cela est désormais possible dès le départ - voir docs.djangoproject.com/en/1.7/ref/applications/…
rhunwicks

Réponses:

182

Django 1.8+

Selon la documentation 1.8 (et la documentation actuelle ),

Les nouvelles applications devraient éviter default_app_config. Au lieu de cela, ils devraient exiger que le chemin pointé vers la AppConfigsous-classe appropriée soit configuré explicitement dans INSTALLED_APPS.

Exemple:

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

Puis modifiez votre AppConfigcomme indiqué ci-dessous.

Django 1.7

Comme indiqué par le commentaire de rhunwicks à OP, c'est désormais possible dès le départ depuis Django 1.7

Tiré de la documentation :

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

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

puis définissez la default_app_configvariable surYourAppConfig

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

Avant Django 1.7

Vous pouvez donner à votre application un nom personnalisé en définissant app_label dans votre définition de modèle. Mais comme django construit la page d'administration, il hachera les modèles par leur app_label, donc si vous voulez qu'ils apparaissent dans une application, vous devez définir ce nom dans tous les modèles de votre application.

class MyModel(models.Model):
        pass
    class Meta:
        app_label = 'My APP name'
Frost.baka
la source
12
J'avais des problèmes avec cela dans l'administrateur. Cela dépend tellement de l'app_label que lorsque j'ai commencé à changer le nom, cela a cassé tout ça.
Joe J
Je sais, j'ai fini par écrire un templatag qui avait un dict avec app_url: app_name binding.
Frost.baka
58
Notez que ce n'est PAS la même chose qu'un nom verbeux, en ce sens qu'il affecte uniquement ce qui est montré à l'utilisateur. C'est la chaîne littérale utilisée pour nommer la table dans la base de données, qui nécessite une migration de schéma si vous modifiez un modèle existant.
Cerin
6
Je ne pense pas que ce soit une bonne solution. Il a trop d'autres effets secondaires qui ne sont pas esthétiques.
David Sanders
Cette réponse populaire recommande d'utiliser un hack / solution de contournement qui était nécessaire avant Django 1.7. Si vous utilisez la version 1.7 ou supérieure, utilisez un fichier apps.py comme recommandé ci-dessous par iMaGiNiX.
shacker
38

Comme indiqué par le commentaire de rhunwicks à OP, c'est désormais possible dès le départ depuis Django 1.7

Tiré de la documentation :

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

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

puis définissez la default_app_configvariable surYourAppConfig

# in yourapp/__init__.py
default_app_config = 'yourapp.apps.YourAppConfig'
r --------- k
la source
Cela fonctionne bien, mais le code du fichier init .py n'est pas requis si vous installez l'application en tant qu'exemple de recommandation Django dans INTALLED_APPS: 'App_name.apps.AppnameConfig'
Roberth Solís
31

Si vous avez plus d'un modèle dans l'application, créez simplement un modèle avec les informations Meta et créez des sous-classes de cette classe pour tous vos modèles.

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

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

Donnez-leur une propriété verbose_name.

N'espérez pas. Vous devrez également copier la vue d'index de django.contrib.admin.sites dans votre propre vue ProjectAdminSite et l'inclure dans votre propre instance d'administration personnalisée:

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

admin.site = ProjectAdminSite()

puis ajustez la vue copiée afin qu'elle utilise votre propriété verbose_name comme étiquette pour l'application.

Je l'ai fait en ajoutant quelque chose d'un peu comme ça à la vue copiée:

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

Pendant que vous peaufinez la vue d'index, pourquoi ne pas ajouter une propriété 'order' également.

Andy Baker
la source
12

Eh bien, j'ai lancé une application appelée todo et j'ai maintenant décidé que je voulais qu'elle s'appelle Tasks . Le problème est que j'ai déjà des données dans ma table, donc mon travail était le suivant. Placé dans le fichier models.py:

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

J'espère que ça aide.

Darren
la source
7

Pour Django 1.4 (pas encore publié, mais le tronc est assez stable), vous pouvez utiliser la méthode suivante. Il repose sur le fait qu'AdminSite renvoie maintenant un TemplateResponse, que vous pouvez modifier avant qu'il ne soit rendu.

Ici, nous faisons un petit peu de patching de singe pour insérer notre comportement, ce qui peut être évité si vous utilisez une sous-classe AdminSite personnalisée.

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)

Cela corrige l'index et les vues app_index. Il ne corrige pas les miettes de pain dans toutes les autres vues d'administration.

spookylukey
la source
7

Vous devez d'abord créer un apps.pyfichier comme celui-ci sur votre dossier d'application:

# appName/apps.py

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

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

Pour charger cette sous-classe AppConfig par défaut:

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

C'est la meilleure façon de faire. testé sur Django 1.7

Mon nom d'application personnalisé

Pour la personne qui a eu des problèmes avec l'espagnol

Ce code active la compatibilité utf-8 sur les scripts python2

# -*- coding: utf-8 -*-
iMaGiNiX
la source
Juste quelques remarques pédantes: créer un fichier nommé apps.pyn'est pas obligatoire. N'importe quel nom est bien (mais vous devez vous y référer __init__.py). Comme déjà indiqué dans d'autres commentaires, ce code fonctionne pour django> = 1.7 ( docs.djangoproject.com/en/1.7/ref/applications/… ).
furins
Cela fonctionne bien, mais le code du fichier init .py n'est pas requis si vous installez l'application en tant qu'exemple de recommandation Django dans INTALLED_APPS: 'App_name.apps.AppnameConfig'
Roberth Solís
6

Non, mais vous pouvez copier le modèle d'administration et y définir le nom de l'application.

temoto
la source
3

Il y a un hack qui peut être fait qui ne nécessite aucune migration. Tiré du blog d'Ionel et le mérite lui revient: http://blog.ionelmc.ro/2011/06/24/custom-app-names-in-the-django-admin/

Il existe également un ticket pour cela qui devrait être corrigé dans Django 1.7 https://code.djangoproject.com/ticket/3591

"" "

Supposons que vous ayez un modèle comme celui-ci:

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

Vous avez verbose_name, mais vous souhaitez également personnaliser app_label pour un affichage différent dans admin. Malheureusement, avoir une chaîne arbitraire (avec des espaces) ne fonctionne pas et ce n'est pas pour l'affichage de toute façon.

Il s'avère que l'administrateur utilise app_label. title () pour l'affichage afin que nous puissions faire un petit hack: str sous-classe avec la méthode de titre remplacée:

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

Maintenant, nous pouvons avoir le modèle comme celui-ci:

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'

et l'administrateur affichera "The stuff box" comme nom de l'application.

"" "

odedfos
la source
2

Si vous avez déjà des tables existantes utilisant l'ancien nom d'application et que vous ne souhaitez pas les migrer, définissez simplement l'app_label sur un proxy du modèle d'origine.

class MyOldModel(models.Model):
    pass

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

Ensuite, il vous suffit de changer cela dans votre admin.py:

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

Sachez que l'URL sera / admin / NewAPPname / mynewmodel / donc vous voudrez peut-être simplement vous assurer que le nom de classe du nouveau modèle ressemble le plus possible à l'ancien modèle.

aigrettes
la source
1

Eh bien, cela fonctionne pour moi. Dans l'app.py, utilisez ceci:

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

Dans setting.py, ajoutez le nom de l'application et le nom de la classe présents dans le fichier app.py dans le dossier de l'application

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
la source
0

Le morceau de code plug-and-play suivant fonctionne parfaitement depuis Django 1.7. Tout ce que vous avez à faire est de copier le code ci-dessous dans le __init__.pyfichier de l'application spécifique et de modifier le VERBOSE_APP_NAMEparamètre.

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 vous l'utilisez pour plusieurs applications, vous devez factoriser la get_current_app_namefonction dans un fichier d'aide.

Vlad Schnakovszki
la source