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?
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?
Réponses:
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 laAppConfig
sous-classe appropriée soit configuré explicitement dansINSTALLED_APPS
.
Exemple:
INSTALLED_APPS = [
# ...snip...
'yourapp.apps.YourAppConfig',
]
Puis modifiez votre AppConfig
comme 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_config
variable 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'
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_config
variable surYourAppConfig
# in yourapp/__init__.py
default_app_config = 'yourapp.apps.YourAppConfig'
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)
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.
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.
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.
Vous devez d'abord créer un apps.py
fichier 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
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 -*-
apps.py
n'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/… ).
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.
"" "
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.
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',
]
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__.py
fichier de l'application spécifique et de modifier le VERBOSE_APP_NAME
paramè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_name
fonction dans un fichier d'aide.