Czy możesz nadać aplikacji Django pełną nazwę do użytku przez administratora?

140

W ten sam sposób, w jaki możesz nadać polom i modelom pełne nazwy, które pojawiają się w panelu administracyjnym Django, czy możesz nadać aplikacji niestandardową nazwę?

rmh
źródło
4
Ten bilet dotyczy tego: code.djangoproject.com/ticket/3591 . Niestety, nie wygląda na to, żeby w najbliższym czasie został zintegrowany z Django ...
Benjamin Wohlwend
10
Od wersji Django 1.7 jest to teraz możliwe po wyjęciu z pudełka - patrz docs.djangoproject.com/en/1.7/ref/applications/ ...
rhunwicks

Odpowiedzi:

182

Django 1.8+

Zgodnie z dokumentami 1.8 (i aktualnymi dokumentami ),

Nowe aplikacje powinny unikać default_app_config. Zamiast tego powinny wymagać AppConfigjawnego skonfigurowania kropkowanej ścieżki do odpowiedniej podklasy INSTALLED_APPS.

Przykład:

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

Następnie zmień swój AppConfigzgodnie z poniższą listą.

Django 1.7

Jak stwierdzono w komentarzu rhunwicks do OP, jest to teraz możliwe po wyjęciu z pudełka od wersji Django 1.7

Zaczerpnięte z dokumentów :

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

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

następnie ustaw default_app_configzmienną naYourAppConfig

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

Przed Django 1.7

Możesz nadać aplikacji niestandardową nazwę, definiując app_label w definicji modelu. Ale gdy django buduje stronę administratora, będzie haszowało modele według ich etykiety_aplikacji, więc jeśli chcesz, aby pojawiały się w jednej aplikacji, musisz zdefiniować tę nazwę we wszystkich modelach aplikacji.

class MyModel(models.Model):
        pass
    class Meta:
        app_label = 'My APP name'
Frost.baka
źródło
12
Miałem z tym problem w panelu administracyjnym. Tak wiele zależy od etykiety app_label, że kiedy zacząłem zmieniać nazwę, zepsuło to wszystko.
Joe J
Wiem, skończyło się na napisaniu szablonu, który miał dykt z wiązaniem app_url: app_name.
Frost.baka
58
Zwróć uwagę, że NIE jest to to samo, co pełna nazwa, w tym sensie, że wpływa tylko na to, co jest pokazywane użytkownikowi. Jest to ciąg literału używany do nazwania tabeli w bazie danych, co wymaga migracji schematu, jeśli zmieniasz istniejący model.
Cerin
6
Nie sądzę, żeby to było dobre rozwiązanie. Ma zbyt wiele innych skutków ubocznych, które nie są estetyczne.
David Sanders,
Ta popularna odpowiedź zaleca użycie hackowania / obejścia, które było potrzebne przed Django 1.7. Jeśli używasz wersji 1.7 lub nowszej, użyj pliku apps.py zgodnie z poniższymi zaleceniami iMaGiNiX.
shacker
38

Jak stwierdzono w komentarzu rhunwicks do OP, jest to teraz możliwe po wyjęciu z pudełka od wersji Django 1.7

Zaczerpnięte z dokumentów :

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

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

następnie ustaw default_app_configzmienną naYourAppConfig

# in yourapp/__init__.py
default_app_config = 'yourapp.apps.YourAppConfig'
r --------- k
źródło
Działa dobrze, ale kod w pliku init .py nie jest wymagany, jeśli zainstalujesz aplikację jako przykład rekomendacji Django w INTALLED_APPS: „Nazwa_aplikacji.apps.AppnameConfig”
Roberth Solís
31

Jeśli masz więcej niż jeden model w aplikacji, po prostu utwórz model z informacjami Meta i utwórz podklasy tej klasy dla wszystkich swoich modeli.

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

class Category(MyAppModel):
     name = models.CharField(max_length=50)
man2xxl
źródło
12

Nadaj im właściwość verbose_name.

Nie rób sobie nadziei. Będziesz także musiał skopiować widok indeksu z django.contrib.admin.sites do własnego widoku ProjectAdminSite i dołączyć go do własnej niestandardowej instancji administratora:

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

admin.site = ProjectAdminSite()

następnie dostosuj skopiowany widok, aby używał Twojej właściwości verbose_name jako etykiety aplikacji.

Zrobiłem to, dodając coś takiego do skopiowanego widoku:

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

Podczas dostosowywania widoku indeksu, dlaczego nie dodać również właściwości „order”.

Andy Baker
źródło
12

Cóż, uruchomiłem aplikację o nazwie todo i zdecydowałem, że chcę, aby nazywała się Zadania . Problem polega na tym, że mam już dane w mojej tabeli, więc moja praca była następująca. Umieszczone w models.py:

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

Mam nadzieję, że to pomoże.

Darren
źródło
7

W przypadku Django 1.4 (jeszcze nie wydanego, ale trunk jest dość stabilny) możesz użyć następującej metody. Opiera się na fakcie, że AdminSite zwraca teraz TemplateResponse, którą możesz zmienić przed renderowaniem.

Tutaj robimy małe poprawki małpy, aby wstawić nasze zachowanie, którego można uniknąć, jeśli używasz niestandardowej podklasy AdminSite.

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)

Naprawia to indeks i widoki app_index. Nie naprawia okruchów chleba we wszystkich innych widokach administratora.

spookylukey
źródło
7

Najpierw musisz utworzyć taki apps.pyplik w swoim folderze aplikacji:

# appName/apps.py

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

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

Aby domyślnie załadować tę podklasę AppConfig:

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

To najlepszy sposób. testowane na Django 1.7

Moja niestandardowa nazwa aplikacji

Dla osoby, która miała problemy z językiem hiszpańskim

Ten kod umożliwia kompatybilność utf-8 ze skryptami python2

# -*- coding: utf-8 -*-
iMaGiNiX
źródło
Tylko kilka pedantycznych uwag dodatkowych: utworzenie pliku o nazwie apps.pynie jest obowiązkowe. Każda nazwa jest w porządku (ale musisz się do niej odwoływać __init__.py). Jak już wspomniano w innych komentarzach, ten kod działa dla django> = 1.7 ( docs.djangoproject.com/en/1.7/ref/applications/ ... ).
furins
Działa dobrze, ale kod w pliku init .py nie jest wymagany, jeśli zainstalujesz aplikację jako przykład rekomendacji Django w INTALLED_APPS: „Nazwa_aplikacji.apps.AppnameConfig”
Roberth Solís
6

Nie, ale możesz skopiować szablon administratora i zdefiniować tam nazwę aplikacji.

temoto
źródło
3

Istnieje hack, który można zrobić, który nie wymaga żadnych migracji. Zaczerpnięte z bloga Ionela i należą do niego: http://blog.ionelmc.ro/2011/06/24/custom-app-names-in-the-django-admin/

Istnieje również bilet na to, który powinien zostać naprawiony w Django 1.7 https://code.djangoproject.com/ticket/3591

„” ”

Załóżmy, że masz taki model:

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

Masz verbose_name, ale chcesz również dostosować app_label do innego wyświetlania w panelu administracyjnym. Niestety posiadanie dowolnego ciągu znaków (ze spacjami) nie działa, a i tak nie jest do wyświetlenia.

Okazuje się, że administrator używa app_label. title () do wyświetlenia, abyśmy mogli zrobić małą podklasę: str z nadpisaną metodą 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

Teraz możemy mieć taki model:

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'

a administrator pokaże „Pole rzeczy” jako nazwę aplikacji.

„” ”

odedfos
źródło
2

Jeśli masz już istniejące tabele używające starej nazwy aplikacji i nie chcesz ich migrować, po prostu ustaw app_label na serwerze proxy oryginalnego modelu.

class MyOldModel(models.Model):
    pass

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

Następnie musisz tylko zmienić to w swoim admin.py:

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

Pamiętaj, że adres URL to / admin / NewAPPname / mynewmodel /, więc możesz po prostu upewnić się, że nazwa klasy dla nowego modelu wygląda jak najbliżej starego modelu.

egrubbs
źródło
1

Cóż, to działa dla mnie. W app.py użyj tego:

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

W setting.py dodaj nazwę aplikacji i nazwę klasy obecną w pliku app.py w folderze aplikacji

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
źródło
0

Poniższy fragment kodu typu plug-and-play działa doskonale od tego czasu Django 1.7. Wszystko, co musisz zrobić, to skopiować poniższy kod do __init__.pypliku konkretnej aplikacji i zmienić VERBOSE_APP_NAMEparametr.

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'

Jeśli używasz tego do wielu aplikacji, powinieneś rozłożyć get_current_app_namefunkcję na plik pomocniczy.

Vlad Schnakovszki
źródło