Können Sie einer Django-App einen ausführlichen Namen für die Verwendung im gesamten Administrator geben?

140

Können Sie einer App einen benutzerdefinierten Namen geben, genauso wie Sie Feldern und Modellen ausführliche Namen geben können, die im Django-Administrator angezeigt werden?

rmh
quelle
4
Dieses Ticket würde dies ansprechen: code.djangoproject.com/ticket/3591 . Leider scheint es nicht so, als würde es bald in Django integriert werden ...
Benjamin Wohlwend
10
Ab Django 1.7 ist dies jetzt sofort möglich - siehe docs.djangoproject.com/de/1.7/ref/applications/…
Rhunwicks

Antworten:

182

Django 1.8+

Gemäß den 1.8 Dokumenten (und aktuellen Dokumenten ),

Neue Anwendungen sollten vermieden werden default_app_config. Stattdessen sollte der gepunktete Pfad zur entsprechenden AppConfigUnterklasse explizit konfiguriert werden müssen INSTALLED_APPS.

Beispiel:

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

Ändern Sie dann Ihre AppConfigwie unten aufgeführt.

Django 1.7

Wie aus Rhunwicks 'Kommentar zu OP hervorgeht, ist dies seit Django 1.7 sofort möglich

Entnommen aus den Dokumenten :

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

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

Setzen Sie dann die default_app_configVariable aufYourAppConfig

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

Vor Django 1.7

Sie können Ihrer Anwendung einen benutzerdefinierten Namen geben, indem Sie app_label in Ihrer Modelldefinition definieren. Da django die Administrationsseite erstellt, werden Modelle anhand ihres app_label gehasht. Wenn Sie also möchten, dass sie in einer Anwendung angezeigt werden, müssen Sie diesen Namen in allen Modellen Ihrer Anwendung definieren.

class MyModel(models.Model):
        pass
    class Meta:
        app_label = 'My APP name'
Frost.baka
quelle
12
Ich hatte Probleme damit im Admin. Es hängt so viel vom app_label ab, dass es das Zeug kaputt machte, als ich anfing, den Namen zu ändern.
Joe J
Ich weiß, am Ende habe ich ein Templatag geschrieben, das ein Diktat mit der Bindung app_url: app_name hatte.
Frost.baka
58
Beachten Sie, dass dies NICHT mit einem ausführlichen Namen identisch ist, da er nur das beeinflusst, was dem Benutzer angezeigt wird. Dies ist die Literalzeichenfolge, mit der die Tabelle in der Datenbank benannt wird. Dies erfordert eine Schemamigration, wenn Sie ein vorhandenes Modell ändern.
Cerin
6
Ich denke nicht, dass dies eine gute Lösung ist. Es hat zu viele andere Nebenwirkungen, die nicht ästhetisch sind.
David Sanders
Diese beliebte Antwort empfiehlt die Verwendung eines Hack / Workarounds, der vor Django 1.7 benötigt wurde. Wenn Sie 1.7 oder höher verwenden, verwenden Sie eine apps.py-Datei, wie unten von iMaGiNiX empfohlen.
Shacker
38

Wie aus Rhunwicks 'Kommentar zu OP hervorgeht, ist dies seit Django 1.7 sofort möglich

Entnommen aus den Dokumenten :

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

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

Setzen Sie dann die default_app_configVariable aufYourAppConfig

# in yourapp/__init__.py
default_app_config = 'yourapp.apps.YourAppConfig'
r --------- k
quelle
Es funktioniert gut, aber der Code in der init .py-Datei ist nicht erforderlich, wenn Sie die Anwendung als Django-Empfehlungsbeispiel in INTALLED_APPS installieren: 'App_name.apps.AppnameConfig'
Roberth Solís
31

Wenn Sie mehr als ein Modell in der App haben, erstellen Sie einfach ein Modell mit den Metainformationen und erstellen Sie Unterklassen dieser Klasse für alle Ihre Modelle.

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

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

Geben Sie ihnen eine verbose_name-Eigenschaft.

Mach dir keine Hoffnungen. Sie müssen auch die Indexansicht von django.contrib.admin.sites in Ihre eigene ProjectAdminSite-Ansicht kopieren und in Ihre eigene benutzerdefinierte Administratorinstanz aufnehmen:

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

admin.site = ProjectAdminSite()

Passen Sie dann die kopierte Ansicht so an, dass Ihre Eigenschaft verbose_name als Bezeichnung für die App verwendet wird.

Ich habe es getan, indem ich der kopierten Ansicht etwas Ähnliches hinzugefügt habe:

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

Fügen Sie während der Optimierung der Indexansicht auch eine 'order'-Eigenschaft hinzu.

Andy Baker
quelle
12

Nun, ich habe eine App namens todo gestartet und jetzt entschieden, dass sie Aufgaben heißen soll . Das Problem ist, dass ich bereits Daten in meiner Tabelle habe, sodass meine Arbeit wie folgt war. Platziert in der models.py:

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

Ich hoffe es hilft.

Darren
quelle
7

Für Django 1.4 (noch nicht veröffentlicht, aber Trunk ist ziemlich stabil) können Sie die folgende Methode verwenden. Es basiert auf der Tatsache, dass AdminSite jetzt eine TemplateResponse zurückgibt, die Sie ändern können, bevor sie gerendert wird.

Hier führen wir ein kleines Affen-Patching durch, um unser Verhalten einzufügen. Dies kann vermieden werden, wenn Sie eine benutzerdefinierte AdminSite-Unterklasse verwenden.

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)

Dadurch werden die Ansichten index und app_index korrigiert. Die Brotkrumen werden in allen anderen Administratoransichten nicht behoben.

Spookylukey
quelle
7

Zuerst müssen Sie eine apps.pyDatei wie diese in Ihrem App-Ordner erstellen:

# appName/apps.py

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

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

So laden Sie diese AppConfig-Unterklasse standardmäßig:

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

Ist der beste Weg zu tun. getestet auf Django 1.7

Mein benutzerdefinierter App-Name

Für die Person, die Probleme mit den Spaniern hatte

Dieser Code aktiviert die utf-8-Kompatibilität für Python2-Skripte

# -*- coding: utf-8 -*-
iMaGiNiX
quelle
Nur ein paar pedantische Randnotizen: Das Erstellen einer Datei mit dem Namen apps.pyist nicht obligatorisch. Jeder Name ist in Ordnung (aber Sie müssen sich in darauf beziehen __init__.py). Wie bereits in anderen Kommentaren erwähnt, funktioniert dieser Code für django> = 1.7 ( docs.djangoproject.com/de/1.7/ref/applications/… ).
Furins
Es funktioniert gut, aber der Code in der init .py-Datei ist nicht erforderlich, wenn Sie die Anwendung als Django-Empfehlungsbeispiel in INTALLED_APPS installieren: 'App_name.apps.AppnameConfig'
Roberth Solís
6

Nein, aber Sie können die Admin-Vorlage kopieren und dort den App-Namen definieren.

temoto
quelle
3

Es kann ein Hack durchgeführt werden, für den keine Migrationen erforderlich sind. Entnommen aus Ionels Blog und Kredit geht an ihn: http://blog.ionelmc.ro/2011/06/24/custom-app-names-in-the-django-admin/

Es gibt auch ein Ticket dafür, das in Django 1.7 behoben werden sollte https://code.djangoproject.com/ticket/3591

"" "

Angenommen, Sie haben ein Modell wie dieses:

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

Sie haben verbose_name, möchten jedoch auch app_label für eine andere Anzeige in admin anpassen. Leider funktioniert es nicht, eine beliebige Zeichenfolge (mit Leerzeichen) zu haben, und sie wird sowieso nicht angezeigt.

Es stellt sich heraus, dass der Administrator app_label verwendet. title () für die Anzeige, damit wir einen kleinen Hack machen können: str-Unterklasse mit überschriebener title-Methode:

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

Jetzt können wir das Modell so haben:

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'

und der Administrator zeigt "The stuff box" als App-Namen an.

"" "

odedfos
quelle
2

Wenn bereits Tabellen mit dem alten App-Namen vorhanden sind und diese nicht migriert werden sollen, legen Sie einfach das app_label auf einem Proxy des Originalmodells fest.

class MyOldModel(models.Model):
    pass

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

Dann müssen Sie dies nur noch in Ihrer admin.py ändern:

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

Beachten Sie, dass die URL / admin / NewAPPname / mynewmodel / lautet. Stellen Sie daher möglicherweise nur sicher, dass der Klassenname für das neue Modell dem alten Modell so nahe wie möglich kommt.

egrubbs
quelle
1

Nun, das funktioniert bei mir. Verwenden Sie in der app.py Folgendes:

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

Fügen Sie in settings.py den Namen der App und den Klassennamen hinzu, der in der Datei app.py im App-Ordner vorhanden ist

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

Der folgende Plug-and-Play-Code funktioniert seitdem einwandfrei Django 1.7. Sie müssen lediglich den folgenden Code in die __init__.pyDatei der jeweiligen App kopieren und den VERBOSE_APP_NAMEParameter ändern .

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'

Wenn Sie dies für mehrere Apps verwenden, sollten Sie die get_current_app_nameFunktion in eine Hilfsdatei umwandeln.

Vlad Schnakovszki
quelle