Can you give a Django app a verbose name for use throughout the admin?
Asked Answered
D

14

160

In the same way that you can give fields and models verbose names that appear in the Django admin, can you give an app a custom name?

Donatus answered 4/3, 2009 at 20:51 Comment(3)
This ticket would address this: code.djangoproject.com/ticket/3591 . Unfortunately, it doesn't seem as it would be integrated into Django anytime soon...Drexler
As of Django 1.7 this is now possible out of the box - see docs.djangoproject.com/en/1.7/ref/applications/…Menedez
As rhunwicks link is dead, here's a working one: docs.djangoproject.com/en/dev/ref/applications/…Jeopardy
L
211

Django 1.8+

Per the 1.8 docs (and current docs),

New applications should avoid default_app_config. Instead they should require the dotted path to the appropriate AppConfig subclass to be configured explicitly in INSTALLED_APPS.

Example:

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

Then alter your AppConfig as listed below.

Django 1.7

As stated by rhunwicks' comment to OP, this is now possible out of the box since Django 1.7

Taken from the docs:

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

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

then set the default_app_config variable to YourAppConfig

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

Prior to Django 1.7

You can give your application a custom name by defining app_label in your model definition. But as django builds the admin page it will hash models by their app_label, so if you want them to appear in one application, you have to define this name in all models of your application.

class MyModel(models.Model):
        pass
    class Meta:
        app_label = 'My APP name'
Leger answered 2/7, 2010 at 8:20 Comment(8)
I was having trouble with this in the admin. So much depends on the app_label that when I started changing the name, it broke that stuff.Monstrous
I know, I ended up writing a templatag which had a dict with app_url:app_name binding.Leger
Note, this is NOT the same as a verbose name, in the sense that it only effects what's shown to the user. It's the literal string used to name the table in the database, which requires a schema migration if you're changing an existing model.Excitability
I don't think this is a good solution. It has too many other side-effects that are not aesthetic.Mundane
This popular answer recommends using a hack/workaround that was needed before Django 1.7. If you're using 1.7 or above, use an apps.py file as recommended below by iMaGiNiX.Quaver
Agree with @rmh, the whole default_app_config is ugly, reminds me of the convoluted management commands setupBuckwheat
It woks well, but the code in init.py file is not required if you install the application as a Django recomendation example in INTALLED_APPS: 'App_name.apps.AppnameConfig'Imbed
essential operation after all here is to relaunch the server to make things workingGammer
S
51

As stated by rhunwicks' comment to OP, this is now possible out of the box since Django 1.7

Taken from the docs:

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

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

then set the default_app_config variable to YourAppConfig

# in yourapp/__init__.py
default_app_config = 'yourapp.apps.YourAppConfig'
Sequestration answered 2/12, 2014 at 17:5 Comment(2)
It woks well, but the code in init.py file is not required if you install the application as a Django recomendation example in INTALLED_APPS: 'App_name.apps.AppnameConfig'Imbed
This is the right answer but you don't need changes in __init__ for Django 3.xKharif
D
31

If you have more than one model in the app just create a model with the Meta information and create subclasses of that class for all your models.

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

class Category(MyAppModel):
     name = models.CharField(max_length=50)
Distraught answered 28/4, 2011 at 13:8 Comment(0)
A
13

Well I started an app called todo and have now decided I want it to be named Tasks. The problem is that I already have data within my table so my work around was as follows. Placed into the models.py:

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

Hope it helps.

Alonso answered 2/9, 2010 at 16:8 Comment(0)
L
12

Give them a verbose_name property.

Don't get your hopes up. You will also need to copy the index view from django.contrib.admin.sites into your own ProjectAdminSite view and include it in your own custom admin instance:

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

admin.site = ProjectAdminSite()

then tweak the copied view so that it uses your verbose_name property as the label for the app.

I did it by adding something a bit like this to the copied view:

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

While you are tweaking the index view why not add an 'order' property too.

Leven answered 5/3, 2009 at 17:29 Comment(0)
S
10

First you need to create a apps.py file like this on your appfolder:

# appName/apps.py

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

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

To load this AppConfig subclass by default:

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

Is the best way to do. tested on Django 1.7

My custom App Name

For the person who had problems with the Spanish

This code enable the utf-8 compatibility on python2 scripts

# -*- coding: utf-8 -*-
Spindrift answered 18/11, 2014 at 6:48 Comment(2)
Just a few pedantic side-notes: creating a file named apps.py is not mandatory. Any name is fine (but you have to refer to it in __init__.py). As already stated in other comments, this code works for django >=1.7 (docs.djangoproject.com/en/1.7/ref/applications/…).Meeting
It woks well, but the code in init.py file is not required if you install the application as a Django recomendation example in INTALLED_APPS: 'App_name.apps.AppnameConfig'Imbed
B
7

For Django 1.4 (not yet released, but trunk is pretty stable), you can use the following method. It relies on the fact that AdminSite now returns a TemplateResponse, which you can alter before it is rendered.

Here, we do a small bit of monkey patching to insert our behaviour, which can be avoided if you use a custom AdminSite subclass.

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)

This fixes the index and the app_index views. It doesn't fix the bread crumbs in all other admin views.

Bankruptcy answered 10/6, 2011 at 22:47 Comment(0)
B
6

No, but you can copy admin template and define app name there.

Baud answered 4/3, 2009 at 23:22 Comment(0)
H
3

There is a hack that can be done that does not require any migrations. Taken from Ionel's blog and credit goes to him: http://blog.ionelmc.ro/2011/06/24/custom-app-names-in-the-django-admin/

There is also a ticket for this that should be fixed in Django 1.7 https://code.djangoproject.com/ticket/3591

"""

Suppose you have a model like this:

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

You have verbose_name, however you want to customise app_label too for different display in admin. Unfortunatelly having some arbitrary string (with spaces) doesn't work and it's not for display anyway.

Turns out that the admin uses app_label. title () for display so we can make a little hack: str subclass with overriden title method:

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

Now we can have the model like this:

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'

and the admin will show "The stuff box" as the app name.

"""

Horseshit answered 11/9, 2014 at 11:24 Comment(0)
F
2

If you already have existing tables using the old app name, and you don't want to migrate them, then just set the app_label on a proxy of the original model.

class MyOldModel(models.Model):
    pass

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

Then you just have to change this in your admin.py:

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

Be aware that the url will be /admin/NewAPPname/mynewmodel/ so you might just want to make sure that the class name for the new model looks as close to the old model as possible.

Footworn answered 3/3, 2014 at 15:32 Comment(0)
D
1

Well, this works for me. In the app.py use this:

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

In setting.py add the name of App and the class name present in app.py file in App folder

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

]

Diann answered 7/11, 2019 at 20:28 Comment(0)
S
1

That's simple just add as follow on your appName/apps

class AppNameConfig(AppConfig):
    default_auto_field = 'default Django'
    name = 'AppName'
    verbose_name = 'Name you Want'
Slippery answered 20/8, 2021 at 17:37 Comment(0)
P
0

The following plug-and-play piece of code works perfectly since Django 1.7. All you have to do is copy the below code in the __init__.py file of the specific app and change the VERBOSE_APP_NAME parameter.

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'

If you use this for multiple apps, you should factor out the get_current_app_name function to a helper file.

Psalter answered 5/1, 2015 at 17:9 Comment(0)
Y
0

Update for 2021 (Django 3.2):

Inside the app.py file of your App you find the AppClientsConfig class. Inside you find the name attribute. Don't change that unless you really have to (and then you will need to also change the app registry inside the settings.py file...etc..).

Instead add an attribute to the class like so to it:

verbose_name = "The Name You Like"

That should do the trick. Feel free to read up more about it on the official Django documentation page.

Yellowbird answered 19/11, 2021 at 1:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.