Bisakah Anda memberi aplikasi Django nama verbose untuk digunakan di seluruh admin?

140

Dengan cara yang sama Anda bisa memberikan bidang dan memodelkan nama verbose yang muncul di admin Django, dapatkah Anda memberi nama kustom pada aplikasi?

rmh
sumber
4
Tiket ini akan membahas ini: code.djangoproject.com/ticket/3591 . Sayangnya, itu tidak tampak seperti itu akan diintegrasikan ke dalam Django dalam waktu dekat ...
Benjamin Wohlwend
10
Pada Django 1.7 ini sekarang mungkin di luar kotak - lihat docs.djangoproject.com/en/1.7/ref/applications/…
rhunwicks

Jawaban:

182

Django 1.8+

Per 1,8 dokumen (dan dokumen saat ini ),

Aplikasi baru harus dihindari default_app_config. Sebagai gantinya mereka harus meminta jalur bertitik ke AppConfigsubkelas yang sesuai untuk dikonfigurasikan secara eksplisit di INSTALLED_APPS.

Contoh:

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

Kemudian ubah AppConfigseperti yang tercantum di bawah ini.

Django 1.7

Seperti yang dinyatakan oleh komentar rhunwicks ke OP, ini sekarang mungkin di luar kotak sejak Django 1.7

Diambil dari dokumen :

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

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

kemudian atur default_app_configvariabel keYourAppConfig

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

Sebelum ke Django 1.7

Anda dapat memberi nama kustom aplikasi Anda dengan mendefinisikan app_label dalam definisi model Anda. Tetapi ketika Django membangun halaman admin, model hash akan ditampilkan oleh app_label mereka, jadi jika Anda ingin mereka muncul dalam satu aplikasi, Anda harus mendefinisikan nama ini di semua model aplikasi Anda.

class MyModel(models.Model):
        pass
    class Meta:
        app_label = 'My APP name'
Frost.baka
sumber
12
Saya mengalami masalah dengan ini di admin. Sangat tergantung pada app_label sehingga ketika saya mulai mengubah nama, itu memecahkan hal itu.
Joe J
Saya tahu, saya akhirnya menulis templatag yang memiliki dict dengan app_url: app_name binding.
Frost.baka
58
Catatan, ini BUKAN sama dengan nama verbose, dalam arti bahwa itu hanya mempengaruhi apa yang ditampilkan kepada pengguna. Ini string literal yang digunakan untuk memberi nama tabel dalam database, yang membutuhkan migrasi skema jika Anda mengubah model yang ada.
Cerin
6
Saya rasa ini bukan solusi yang baik. Ini memiliki terlalu banyak efek samping lain yang tidak estetika.
David Sanders
Jawaban populer ini merekomendasikan penggunaan hack / solusi yang diperlukan sebelum Django 1.7. Jika Anda menggunakan 1,7 atau lebih, gunakan file apps.py seperti yang direkomendasikan di bawah ini oleh iMaGiNiX.
shacker
38

Seperti yang dinyatakan oleh komentar rhunwicks ke OP, ini sekarang mungkin di luar kotak sejak Django 1.7

Diambil dari dokumen :

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

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

kemudian atur default_app_configvariabel keYourAppConfig

# in yourapp/__init__.py
default_app_config = 'yourapp.apps.YourAppConfig'
r --------- k
sumber
Ini bekerja dengan baik, tetapi kode dalam file init .py tidak diperlukan jika Anda menginstal aplikasi sebagai contoh rekomendasi Django di INTALLED_APPS: 'App_name.apps.AppnameConfig'
Roberth Solís
31

Jika Anda memiliki lebih dari satu model dalam aplikasi, buat saja model dengan informasi Meta dan buat subkelas dari kelas itu untuk semua model Anda.

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

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

Beri mereka properti verbose_name.

Jangan terlalu berharap. Anda juga perlu menyalin tampilan indeks dari django.contrib.admin.sites ke dalam tampilan ProjectAdminSite Anda sendiri dan memasukkannya dalam instance admin kustom Anda sendiri:

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

admin.site = ProjectAdminSite()

kemudian atur tampilan yang disalin sehingga menggunakan properti verbose_name Anda sebagai label untuk aplikasi.

Saya melakukannya dengan menambahkan sesuatu seperti ini ke tampilan yang disalin:

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

Saat Anda mengubah tampilan indeks mengapa tidak menambahkan properti 'pesanan' juga.

Andy Baker
sumber
12

Yah saya memulai aplikasi yang disebut todo dan sekarang memutuskan saya ingin itu diberi nama Tugas . Masalahnya adalah bahwa saya sudah memiliki data di dalam tabel saya sehingga pekerjaan saya adalah sebagai berikut. Ditempatkan ke dalam models.py:

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

Semoga ini bisa membantu.

darren
sumber
7

Untuk Django 1.4 (belum dirilis, tetapi trunk cukup stabil), Anda dapat menggunakan metode berikut. Itu bergantung pada fakta bahwa AdminSite sekarang mengembalikan TemplateResponse, yang dapat Anda ubah sebelum diberikan.

Di sini, kami melakukan sedikit tambalan monyet untuk menyisipkan perilaku kami, yang dapat dihindari jika Anda menggunakan subkelas AdminSite khusus.

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)

Ini memperbaiki indeks dan tampilan app_index. Itu tidak memperbaiki remah roti di semua tampilan admin lainnya.

spookylukey
sumber
7

Pertama, Anda perlu membuat apps.pyfile seperti ini di appfolder Anda:

# appName/apps.py

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

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

Untuk memuat subkelas AppConfig ini secara default:

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

Apakah cara terbaik untuk melakukannya. diuji pada Django 1.7

Nama Aplikasi kustom saya

Untuk orang yang memiliki masalah dengan bahasa Spanyol

Kode ini mengaktifkan kompatibilitas utf-8 pada skrip python2

# -*- coding: utf-8 -*-
iMaGiNiX
sumber
Hanya beberapa catatan samping yang bagus: membuat file bernama apps.pytidak wajib. Nama apa pun baik-baik saja (tetapi Anda harus merujuknya __init__.py). Seperti yang telah dinyatakan dalam komentar lain, kode ini berfungsi untuk django> = 1.7 ( docs.djangoproject.com/en/1.7/ref/applications/… ).
Furins
Ini bekerja dengan baik, tetapi kode dalam file init .py tidak diperlukan jika Anda menginstal aplikasi sebagai contoh rekomendasi Django di INTALLED_APPS: 'App_name.apps.AppnameConfig'
Roberth Solís
6

Tidak, tetapi Anda dapat menyalin template admin dan menentukan nama aplikasi di sana.

temoto
sumber
3

Ada peretasan yang bisa dilakukan yang tidak memerlukan migrasi apa pun. Diambil dari blog Ionel dan penghargaan diberikan kepadanya: http://blog.ionelmc.ro/2011/06/24/custom-app-names-in-the-django-admin/

Ada juga tiket untuk ini yang harus diperbaiki di Django 1.7 https://code.djangoproject.com/ticket/3591

"" "

Misalkan Anda memiliki model seperti ini:

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

Anda memiliki verbose_name, namun Anda juga ingin menyesuaikan app_label untuk tampilan yang berbeda di admin. Sayangnya memiliki beberapa string arbitrer (dengan spasi) tidak berfungsi dan itu bukan untuk tampilan.

Ternyata admin menggunakan app_label. title () untuk tampilan sehingga kita dapat membuat sedikit hack: str subclass dengan metode title 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

Sekarang kita dapat memiliki model seperti ini:

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'

dan admin akan menampilkan "Kotak barang" sebagai nama aplikasi.

"" "

odedfos
sumber
2

Jika Anda sudah memiliki tabel yang ada menggunakan nama aplikasi lama, dan Anda tidak ingin memigrasikannya, maka atur app_label pada proksi model asli.

class MyOldModel(models.Model):
    pass

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

Maka Anda hanya perlu mengubah ini di admin.py Anda:

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

Perlu diketahui bahwa url akan menjadi / admin / NewAPPname / mynewmodel / jadi Anda mungkin hanya ingin memastikan bahwa nama kelas untuk model baru terlihat sedekat mungkin dengan model lama.

egrubbs
sumber
1

Ya, ini bekerja untuk saya. Di app.py gunakan ini:

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

Di setting.py tambahkan nama App dan nama kelas yang ada di file app.py di folder App

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

Potongan kode plug-and-play berikut berfungsi dengan baik sejak itu Django 1.7. Yang harus Anda lakukan adalah menyalin kode di bawah ini dalam __init__.pyfile aplikasi tertentu dan mengubah VERBOSE_APP_NAMEparameternya.

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'

Jika Anda menggunakan ini untuk beberapa aplikasi, Anda harus memfaktorkan get_current_app_namefungsi tersebut ke file pembantu.

Vlad Schnakovszki
sumber