how to modify admin page to add extra columns? - python

can anybody explain how to add more columns in django admin page.
and how the meta class works, how it adds the columns from list
class SignUpAdmin(admin.ModelAdmin): # what is ModelAdmin class
list_display = ['__unicode__','timestamp'] # columns created in models file
class Meta:
model = SignUp # SignUp class created as Model class in model.py file
admin.site.register(Signenter code hereUp, SignIpAdmin)

you don't need to use Meta class in your admin class. when you want to add database columns to your admin UI just pass them in your list_display=['title', 'timestamp',] array

Related

Make models fields readonly in all admin pages

My project has multiple Models and custom admin pages for the models. All the Models inherit from a "BaseModel". For business functionality, we had to update our "Base model" to include 2 new fields. Given that all models inherit these 2 new fields, they are now showing up in admin pages as editable fields. As per business functionality, these two fields should be displayed as read-only fields
For making fields readonly we normally use readonly_fields = [read only..] in admin class. Is there a way to achieve this without touching all the admin classes?
Create a base admin model class and use it on every admin model class. AFAIK, it will be the best solution you can have
from django.contrib import admin
class BaseModelAdmin:
"""
The base model admin class
"""
readonly_fields = ["field_1", "field_2"]
class FooModelAdmin(BaseModelAdmin, admin.ModelAdmin):
"""
Inheriting the 'BaseModelAdmin' class here
"""
...
class BarModelAdmin(BaseModelAdmin, admin.ModelAdmin):
"""
Inheriting the 'BaseModelAdmin' class here
"""
def get_readonly_fields(self, request, obj=None):
"""
If you have "readonly_fields" that are specific to certain Model, override this method
"""
readonly_fields = super().get_readonly_fields(request, obj=None) + ["bar_field_1", "bar_field_2"]
return readonly_fields
admin.site.register(FooModel, FooModelAdmin) # registering the model in Django admin
admin.site.register(BarModel, BarModelAdmin) # registering the model in Django admin

Django - Change Fields in Group Admin Model

The built-in django group model on the admin site only shows name:
but I want to include additional fields that are already part of the group model, such as id.
I have tried adding these fields using the following admin.py setup:
from django.contrib import admin
from django.contrib.auth.models import Group
class GroupsAdmin(admin.ModelAdmin):
list_display = ["name", "pk"]
class Meta:
model = Group
admin.site.register(Group, GroupsAdmin)
But this returns the error:
django.contrib.admin.sites.AlreadyRegistered: The model Group is already registered.
I have successfully registered other models (I've created) on admin but the above doesn't work for those models that are already a part of django.
How can I add fields in the admin model for Group?
The accepted answer is correct, however, I would like to point out that you could inherit from the GroupAdmin if your goal is only extending that is, and not modifying:
from django.contrib.auth.admin import GroupAdmin
class GroupsAdmin(GroupAdmin):
list_display = ["name", "pk"]
admin.site.unregister(Group)
admin.site.register(Group, GroupsAdmin)
You need to unregister it first from the built-in Group model and then register it again with your custom GroupAdmin model.
So:
class GroupsAdmin(admin.ModelAdmin):
list_display = ["name", "pk"]
class Meta:
model = Group
admin.site.unregister(Group)
admin.site.register(Group, GroupsAdmin)
Also, the Meta class is not required. You can remove it.

Indirect inline in Django admin

I have the following models:
class UserProfile(models.Model):
user = models.OneToOneField(User)
class Property(models.Model):
user = models.ForeignKey(User)
I would like to create a TabularInline displaying every Property connected to a particular UserProfile on its Django admin page. The problem here is, of course, that Property does not have a ForeignKey directly to UserProfile, so I cannot simply write
class PropertyTabularInline(admin.TabularInline):
model = Property
class UserProfileAdmin(admin.ModelAdmin):
inlines = (PropertyTabularInline,)
How can I easily do what I want?
You can overwrite the User admin page to display both the Profile and the Property models.
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from myapp.models import *
class ProfileInline(admin.TabularInline):
model = Profile
class PropertyInline(admin.TabularInline):
model = Property
class UserAdmin(UserAdmin):
inlines = (ProfileInline, PropertyInline,)
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
You can also remove any unwanted/unused User properties from being displayed (e.g. Groups or Permissions)
more here: https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#extending-the-existing-user-model
and here:
https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#a-full-example
class PropertyTabularInline(admin.TabularInline):
model = Property
def formfield_for_dbfield(self, field, **kwargs):
if field.name == 'user':
# implement your method to get userprofile object from request here.
user_profile = self.get_object(kwargs['request'], UserProfile)
kwargs["queryset"] = Property.objects.filter(user=user_profile)
return super(PropertyInLine, self).formfield_for_dbfield(field, **kwargs)
once this is done, you can add this inline to user UserProfileAdmin like:
class UserProfileAdmin(admin.ModelAdmin):
inlines = (PropertyTabularInline,)
Haven't tested it, but that should work.
It is achievable by making one change in your models.
Instead of creating OneToOne relationship from UserProfile to User, subclass User creating UserProfile. Code should look like that:
class UserProfile(User):
# some other fields, no relation to User model
class Property(models.Model):
user = models.ForeignKey(User)
That will result in creating UserProfile model that have hidden OneToOne relation to User model, it won't duplicate user model.
After doing that change, your code will work. There are some changes under the hood, like UserProfile no longer have it's own ID, you can access fields from User inside UserProfile and it's hard to swap User model using settings.AUTH_USER_MODEL (that will require creating some custom function returning proper type and changing migration by hand) but if this is not a problem for you, it may be good solution.

How can i remove extra "s" from django admin panel?

I am really very much irritated by the extra "s" added after my class name in django admin eg class 'About' in my model.py becomes 'Abouts' in admin section. And i want it not to add extra 's'. Here is my model.py file-
class About(models.Model):
about_desc = models.TextField(max_length=5000)
def __unicode__(self): # __str__ on Python 3
return str(self.about_desc)
Please anybody suggest me how django can solve my problem.
You can add another class called Meta in your model to specify plural display name. For example, if the model's name is Category, the admin displays Categorys, but by adding the Meta class, we can change it to Categories.
I have changed your code to fix the issue:
class About(models.Model):
about_desc = models.TextField(max_length=5000)
def __unicode__(self): # __str__ on Python 3
return str(self.about_desc)
class Meta:
verbose_name_plural = "about"
For more Meta options, refer to https://docs.djangoproject.com/en/1.8/ref/models/options/
Take a look at the Model Meta in the django documentation.
Within a Model you can add class Meta this allows additional options for your model which handles things like singular and plural naming.
This can be used in the following way (in english we do not have sheeps) so verbose_name_plural can be used to override djangos attempt at pluralising words:
class Sheep(model.Model):
class Meta:
verbose_name_plural = 'Sheep'
inside model.py or inside your customized model file add class meta within a Model Class.
If not mentioned then a extra 's' will be added at the end of Model Class Name which will be visible in Django Admin Page.
class TestRoles(model.Model):
class Meta: verbose_name_plural = 'TestRoles'

Same Options For Different Django Admin Class

This should evident but I dont know how to do it.
How do I Apply the same options for instance a exclude for different model and different admin class
-- admin.py
class Tabla1(admin.ModelAdmin):
exclude('tenant')
...
class Tabla2(admin.ModelAdmin):
exclude('tenant')
...
class Tabla3(admin.ModelAdmin):
exclude('tenant')
...
That I want is exclude the same tenant field in the tables. I have the same field in several tables. In fact I have several actions(same actions) to do for the different admin models.
Just make a base admin class that you can inherit from:
class TablaBaseAdmin(admin.ModelAdmin):
class Meta:
exclude = ('tenant',)
class Tabla1Admin(TablaBaseAdmin):
pass
class Tabla2Admin(TablaBaseAdmin):
pass
class Tabla3Admin(TablaBaseAdmin):
pass

Categories

Resources