Puoi dare a un'app Django un nome dettagliato da usare in tutto l'amministratore?


140

Allo stesso modo in cui puoi assegnare a campi e modelli nomi dettagliati che compaiono nell'amministratore di Django, puoi assegnare a un'app un nome personalizzato?


4
Questo biglietto verrebbe indirizzato a questo: code.djangoproject.com/ticket/3591 . Sfortunatamente, non sembra che sarebbe presto integrato in Django ...
Benjamin Wohlwend,

10
A partire da Django 1.7 questo è ora possibile pronto
all'uso

Risposte:


182

Django 1.8+

Secondo i 1,8 documenti (e i documenti correnti ),

Le nuove applicazioni dovrebbero evitare default_app_config. Dovrebbero invece richiedere la AppConfigconfigurazione esplicita del percorso punteggiato della sottoclasse appropriata INSTALLED_APPS.

Esempio:

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

Quindi modifica il tuo AppConfigcome elencato di seguito.

Django 1.7

Come affermato dal commento di rhunwicks a OP, questo è ora possibile dal momento che Django 1.7

Tratto dai documenti :

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

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

quindi impostare la default_app_configvariabile suYourAppConfig

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

Prima di Django 1.7

È possibile assegnare un nome personalizzato all'applicazione definendo app_label nella definizione del modello. Ma poiché django costruisce la pagina di amministrazione, avrà i modelli con l'hash della loro app_label, quindi se vuoi che appaiano in una applicazione, devi definire questo nome in tutti i modelli della tua applicazione.

class MyModel(models.Model):
        pass
    class Meta:
        app_label = 'My APP name'

12
Ho avuto problemi con questo nell'amministratore. Molto dipende dalla etichetta_app che quando ho iniziato a cambiare il nome, ha rotto quella roba.
Joe J,

Lo so, ho finito per scrivere un templatag che aveva un dict con app_url: app_name binding.
Frost.baka,

58
Nota, questo NON è lo stesso di un nome dettagliato, nel senso che influenza solo ciò che viene mostrato all'utente. È la stringa letterale utilizzata per denominare la tabella nel database, che richiede una migrazione dello schema se si modifica un modello esistente.
Cerin,

6
Non credo sia una buona soluzione. Ha troppi altri effetti collaterali che non sono estetici.
David Sanders,

Questa popolare risposta consiglia di utilizzare un trucco / soluzione alternativa necessario prima di Django 1.7. Se stai utilizzando 1.7 o versioni successive, utilizza un file apps.py come raccomandato di seguito da iMaGiNiX.
shacker

38

Come affermato dal commento di rhunwicks a OP, questo è ora possibile dal momento che Django 1.7

Tratto dai documenti :

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

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

quindi impostare la default_app_configvariabile suYourAppConfig

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

Si sveglia bene, ma il codice nel file init .py non è richiesto se si installa l'applicazione come esempio di raccomandazione Django in INTALLED_APPS: 'App_name.apps.AppnameConfig'
Roberth Solís

31

Se hai più di un modello nell'app, crea un modello con le informazioni Meta e crea sottoclassi di quella classe per tutti i tuoi modelli.

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

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

12

Assegna loro una proprietà verbose_name.

Non sperare. Dovrai anche copiare la vista indice da django.contrib.admin.sites nella tua vista ProjectAdminSite e includerla nella tua istanza di amministratore personalizzata:

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

admin.site = ProjectAdminSite()

quindi modifica la vista copiata in modo che utilizzi la proprietà verbose_name come etichetta per l'app.

L'ho fatto aggiungendo qualcosa di simile alla vista copiata:

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

Mentre stai modificando la vista indice, perché non aggiungere anche una proprietà 'order'.


12

Bene, ho avviato un'app chiamata todo e ora ho deciso che voglio che si chiami Task . Il problema è che ho già dei dati nella mia tabella, quindi il mio lavoro è stato il seguente. Inserito in models.py:

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

Spero che sia d'aiuto.


7

Per Django 1.4 (non ancora rilasciato, ma trunk è piuttosto stabile), è possibile utilizzare il seguente metodo. Si basa sul fatto che AdminSite ora restituisce un TemplateResponse, che è possibile modificare prima del rendering.

Qui, facciamo un po 'di patch scimmia per inserire il nostro comportamento, che può essere evitato se si utilizza una sottoclasse AdminSite personalizzata.

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)

Ciò corregge l'indice e le visualizzazioni app_index. Non corregge le briciole di pane in tutte le altre viste di amministrazione.


7

Per prima cosa devi creare un apps.pyfile come questo sulla tua cartella dell'app:

# appName/apps.py

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

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

Per caricare questa sottoclasse AppConfig per impostazione predefinita:

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

È il modo migliore di fare. testato su Django 1.7

Il mio nome app personalizzato

Per la persona che ha avuto problemi con gli spagnoli

Questo codice abilita la compatibilità utf-8 su script python2

# -*- coding: utf-8 -*-

Solo alcune note secondarie pedanti: la creazione di un file denominato apps.pynon è obbligatoria. Qualsiasi nome va bene (ma devi fare riferimento ad esso in __init__.py). Come già affermato in altri commenti, questo codice funziona per django> = 1.7 ( docs.djangoproject.com/en/1.7/ref/applications/… ).
furine il

Si sveglia bene, ma il codice nel file init .py non è richiesto se si installa l'applicazione come esempio di raccomandazione Django in INTALLED_APPS: 'App_name.apps.AppnameConfig'
Roberth Solís

6

No, ma puoi copiare il modello di amministratore e definire il nome dell'app lì.


3

C'è un trucco che può essere fatto che non richiede alcuna migrazione. Tratto dal blog di Ionel e il merito va a lui: http://blog.ionelmc.ro/2011/06/24/custom-app-names-in-the-django-admin/

C'è anche un biglietto per questo che dovrebbe essere risolto in Django 1.7 https://code.djangoproject.com/ticket/3591

"""

Supponiamo di avere un modello come questo:

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

Hai verbose_name, tuttavia vuoi personalizzare anche app_label per diversi display in admin. Sfortunatamente avere una stringa arbitraria (con spazi) non funziona e non è comunque visibile.

Si scopre che l'amministratore utilizza app_label. title () per la visualizzazione in modo da poter fare un piccolo hack: sottoclasse str con il metodo del titolo overriden:

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

Ora possiamo avere il modello in questo modo:

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 l'amministratore mostrerà "The stuff box" come nome dell'app.

"""


2

Se disponi già di tabelle esistenti che utilizzano il vecchio nome dell'app e non desideri migrarle, imposta semplicemente app_label su un proxy del modello originale.

class MyOldModel(models.Model):
    pass

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

Quindi devi solo cambiarlo nel tuo admin.py:

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

Tieni presente che l'URL sarà / admin / NewAPPname / mynewmodel /, quindi potresti voler solo assicurarti che il nome della classe per il nuovo modello sia il più vicino possibile al vecchio modello.


1

Bene, questo funziona per me. In app.py usa questo:

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

In setting.py aggiungi il nome dell'App e il nome della classe presente nel file app.py nella cartella App

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

]


0

Il seguente codice plug-and-play funziona perfettamente da allora Django 1.7. Tutto quello che devi fare è copiare il codice seguente nel __init__.pyfile dell'app specifica e modificare il VERBOSE_APP_NAMEparametro.

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 lo usi per più app, dovresti scomporre la get_current_app_namefunzione in un file di supporto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.