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?
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'
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'
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)
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.
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.
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
For the person who had problems with the Spanish
This code enable the utf-8 compatibility on python2 scripts
# -*- coding: utf-8 -*-
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.
No, but you can copy admin template and define app name there.
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.
"""
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.
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',
]
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'
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.
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.
Does anyone know, how to register child class derived from abstract class in admin.py (the abstract class is in file abstract_models.py file) I tried major solution in the web but does not seem to work. It is possible as pointed by various contributors but don't know what I am doing wrong!
My folder structure is like this
'''
gaasc/ <- project folder
contain urls.py, admin.py,models.py,etc
gaasc_apps/<- contains all apps
core/
abstract_models.py
models.py
admin.py,...
about_app/
models.py,
admin.py
urls.py
'''
I am trying to leverage abstract class inside core app to models inside about_app app. Yes, between different apps.
Steps followed:
create abstract_models.py and define abstract class
import it in core/models.py
3.import the abstract class from core/models.py inside about_app/models.py
register the class in about_app/models.py to admin.py(in about_app/)
abstract_models.py file(inside core/abstract_models.py) has
import uuid
from django.db import models
class AbstractTimeStampModel(models.Model):
"""TimeStampModel that holds created_date and updated_date field"""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
created_date = models.DateTimeField("Created date", auto_now_add=True)
updated_date = models.DateTimeField("Updated date", auto_now=True)
def __str__(self):
return self.created_date
class Meta:
abstract = True
class AbstractTextAreaOnly(AbstractTimeStampModel):
"""Abstract class for textfield"""
about = models.TextField(
verbose_name="Description",
blank=True
)
def __str__(self):
return "Textonly class-"+self.id
class Meta:
ordering = ['created_date']
models.py in core/models.py
from django.db import models
from .abstract_models import (
AbstractTextAreaOnly,
)
Now I want to use this abstract class in about_app/
So my derived class in models.py inside about_app/models.py looks:
from django.db import models
from gaasc_apps.core.models import(
AbstractTextAreaOnly,
)
class GeneralInformation(AbstractTextAreaOnly):
'''
Gives general information of college
'''
class Meta():
db_table = "general_information"
verbose_name="General information"
ordering=['created_date']
What I tried:
I tried to registering using following ways:
method1:
in admin.py in about_app/admin.py:
from django.contrib import admin
from .models import (
GeneralInformation,
)
#register(GeneralInformation)
class GeneralInformationAdmin(admin.ModelAdmin):
pass
method 2:
in about_app/admin.py
from django.contrib import admin
from .models import (
GeneralInformation,
)
class GeneralInformationAdmin(admin.ModelAdmin):
pass
admin.site.register(GeneralInformation,GeneralInformationAdmin)
method3:
in about_app/admin.py
......
class GeneralInformationAdmin(admin.ModelAdmin):
readonly_fields = ('id','about','created_date','updated_date')
list_display=('id','about','created_date')
fieldsets=[
('Id',{'fields':['id']}),
('About',{'fields':['about']}),
('Created_Date',{'fields':['created_date']}),
]
admin.site.register(GeneralInformation,GeneralInformationAdmin)
With all this solution GeneralInformation is not shown in admin panal/dashboard of django.
The solution seems to be simple but I don't know why its not working?
Some solution I tried are here:
How to register inherited sub class in admin.py file in django?
Django admin model Inheritance is it possible?
Register abstract model in admin django 1.6
VERSION:
Django-2.2
python-3.6
I have found the solution to the problem , it was simple
we need to define config setting in each apps. Due to lack of config setting and perticular directory structure it was not able to read it.E.g.
in about_app/__init__.py :
default_app_config = "gaasc_apps.about_app.apps.AboutAppConfig"
and in about_app/apps.py we should have like this
from django.apps import AppConfig
class AboutAppConfig(AppConfig):
name = 'gaasc_apps.about_app'
verbose_name="about application"
def ready(self):
pass
enter image description here
I have created a model named 'Questions' in my app.Please see the attached image.
here my app name is 'polls'.Is it possible to change in admin view?
You could change verbose_name on app_config
*this works for Django 1.7+
for prior version each Model should have
class Meta:
app_label = 'Not Polls'
set
You must add this line to apps.py file inside Config Class
verbose_name = 'Text'
For example:
class PollsConfig(AppConfig):
name = 'core'
verbose_name = 'Your Text'
I am doing a small blog in Mezzanine for learning purpose and wanted to add a custom content type by sub-classing "mezzanine.pages.models.Page" and registering this model with admin. My classes look something like this:
models.py:
from django.db import models
from mezzanine.pages.models import Page
class Student(Page):
dob = models.DateField("Date of birth")
name = models.CharField("Name", max_length=30)
gender = models.CharField("Gender", max_length = 5, choices=(('M','Male'),
('F','Female')), default = 'M')
image = models.ImageField(upload_to='Students')
class Project(models.Model):
student = models.ForeignKey("Student")
project_image = models.ImageField(upload_to="StudentProjects")
admin.py:
from copy import deepcopy
from django.contrib import admin
from mezzanine.pages.admin import PageAdmin
from .models import Student, Project
student_extra_fieldsets = ((None, {"fields": ("dob","name","gender","image")}),)
class ProjectInline(admin.TabularInline):
model = Project
class StudentAdmin(PageAdmin):
inlines = (ProjectInline,)
fieldsets = deepcopy(PageAdmin.fieldsets) + student_extra_fieldsets
admin.site.register(Student, StudentAdmin)
Now, when I visit "http://localhost:8000/admin/pages/page/" to add my newly registered content type, I get an empty option with no name, but when I select I get the Custom Content type "Student" Page to add and edit.
Since I have just started with Django and Mezzanine, I cannot simply figure it out.
I am using "sqlite" as backend and not using "South"
Any pointers to this??
Thanx for your help :)
I removed that "*name = models.CharField("Name", max_length=30)*" in models.py and replaced it with:
first_name = models.CharField("First Name", max_length=30)
last_name = models.CharField("Last Name", max_length=30)
And now every thing seems OK!!. (Only if I used "South"
How can I change content_css option in django-tinymce for various objects? I mean that when I use tinymce for model1 then content_css is model1.css and when for model2 then model2.css.
I use
I found out that I can pass extra arguments for tiny_mce in Meta class:
class Meta:
model = MyModel
widgets = {
'field_name': TinyMCE(mce_attrs={'content_css': "style.css"}),
}
Thanks for the szaman's reply, I'll try to describe the process for beginners in new versions of Django (1.9), how to add custom css files to the field named 'text' in the Post model in the Django's admin
Change fields' type in models.py to HTMLField
from tinymce.models import HTMLField
class Post(models.Model):
title = models.TextField(default='')
subtitle = models.TextField(default='')
text = HTMLField(default='')
In the application with the required model, add to admin.py file:
#admin.register(Post) # decorator for adding Django admin for Post
class PostAdmin(admin.ModelAdmin):
form = PostForm # attach custom form
Add form's class
from tinymce.widgets import TinyMCE
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = '__all__' # required in Django (>=1.8)
widgets = {
'text': TinyMCE(mce_attrs={'content_css': ["path_to_css_file",]}),
}