Serial number in Django admin list view - python

I have the following list view in Django admin. How do I show serial number for every entry? Meaning numbering the list given in the list below. Also, this serial number should also take into account the pagination of the list.
Here is the model:
class Staff(User):
INITIALS = (
("MR", "Mr."),
("MRS", "Mrs."),
("MS", "Ms."),
)
initials = models.CharField(
max_length=10,
choices=INITIALS,
default="MR"
)
def __str__(self):
return self.initials+" "+self.first_name+" "+self.last_name
# Control model features
class Meta:
verbose_name = 'Staff'
verbose_name_plural = 'Staff'
Here is the admin model:
#admin.register(Staff)
class StaffAdmin(BaseUserAdmin):
add_form = StaffCreationForm
add_fieldsets = (
(None, {
'fields': ('email', 'password1', 'password2', 'first_name', 'last_name','institute','groups')
}),
)
fieldsets = (
(None, {'fields': ('email', 'first_name', 'last_name','password','groups','institute')}),
)
list_filter = ('institute',)
inlines = [
SubjectTeacher
]
list_display = ("first_name", "last_name")
list_per_page = 5

I don't see a "serial number" field in your Staff model but I believe you are referring to its id
in your admin model you should be able to just include id to add the "serial number"
#admin.register(Staff)
class StaffAdmin(BaseUserAdmin):
add_form = StaffCreationForm
add_fieldsets = (
(None, {
'fields': ('email', 'password1', 'password2', 'first_name', 'last_name','institute','groups')
}),
)
fieldsets = (
(None, {'fields': ('email', 'first_name', 'last_name','password','groups','institute')}),
)
list_filter = ('institute',)
inlines = [
SubjectTeacher
]
list_display = ("first_name", "last_name", "id")
list_per_page = 5

In the list view you also need to include the serial number. You should share with us how you are expressing this view in code, instead of the screen shot to clarify the question

Related

for model in model_or_iterable: TypeError: 'MediaDefiningClass' object is not iterable

I encountered a problem to migrate this model and this admin
python manage.py makemigrations
This error occurs
for model in model_or_iterable:
TypeError: 'MediaDefiningClass' object is not iterable
this is my admin
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import Group
from .models import User, Province
class MyUserAdmin(UserAdmin):
fields = (
(None, {'fields': ('username', 'password')}),
'Personal info', {'fields': ('first_name', 'last_name', 'phone_number', 'email')},
'Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser',
'groups', 'user_permissions')},
'Important dates', {'fields': ('last_login', 'date_joined')},
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'phone_number', 'password1', 'password2'),
}),
)
list_display = ('username', 'phone_number', 'email', 'is_staff')
search_fields = ('username_exact',)
ordering = ('-id',)
def get_search_results(self, request, queryset, search_term):
queryset, my_have_duplicates = super().get_search_results(
request, queryset, search_term
)
try:
search_term_as_int = int(search_term)
except ValueError:
pass
else:
queryset |= self.model.objects.filter(phone_number=search_term_as_int)
return queryset, my_have_duplicates
admin.site.unregister(Group)
admin.site.register(Province)
admin.site.register(User)
admin.site.register(MyUserAdmin)
But the program has encountered an error
for model in model_or_iterable:
TypeError: 'MediaDefiningClass' object is not iterable

Fieldsets don't do anything in admin django

I'm learning Django and found that we can use fieldsets to customise the way admin creation form looks like. Here is the code I'am using:
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = CustomUser
list_display = ('email', 'age', 'is_staff', 'is_active',)
list_filter = ('email', 'age', 'is_staff', 'is_active',)
fieldsets = (
('Advanced options', {
'classes': ('wide',),
'fields': ('email', 'age', 'is_staff', 'is_active',),
}),
)
admin.site.register(CustomUser, CustomUserAdmin)
Here is the result:
As you can see this "fieldsets" does nothing for this creation page. And if I completely remove this "fieldsets" nothing will change. What I did wrong here? I want my fieldsets work.
Thank you!
The UserAdmin separates the add action (user creation) form other actions. This is because it only wants to deal with username and password and then the rest of the fields.
So the UserAdmin does some special work and you have both fieldsets and add_fieldsets.
Below is copied from a customer user in one of my projects. It has a required field on the User model called display_name and so it must be submitted via the admin as well.
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as AuthUserAdmin
from django.utils.translation import gettext as _
from core import models
from core.forms.admin import UserCreationForm
#admin.register(models.User)
class UserAdmin(AuthUserAdmin):
fieldsets = (
(None, {"fields": ("username", "password")}),
(_("Personal info"), {"fields": ("display_name", "email")}),
(
_("Permissions"),
{
"fields": (
"is_active",
"is_staff",
"is_superuser",
"groups",
"user_permissions",
),
},
),
(_("Important dates"), {"fields": ("last_login", "date_joined")}),
)
add_fieldsets = (
(
None,
{"classes": ("wide",), "fields": ("username", "password1", "password2"),},
),
(_("Profile related"), {"fields": ("display_name",)}),
)
add_form = UserCreationForm

Extendings Django's UserCreationForm

I'm trying to extend Django's django.contrib.auth.forms.UserCreationForm to include email and name fields. My similar extension of the UserChangeForm works fine, but UserCreationForm still only shows the default username, password1, and password2 fields. Any ideas what I'm doing wrong?
forms.py
class AuthorCreation(UserCreationForm):
class Meta:
model = User
fields = ('username', 'password1', 'password2',
'first_name', 'last_name', 'email', 'groups', 'is_staff')
class AuthorChange(UserChangeForm):
class Meta:
model = User
fields = ('username', 'first_name', 'last_name',
'email', 'password', 'groups', 'is_staff')
admin.py
class AuthorAdmin(UserAdmin):
"""Admin class for creating and managing Authors"""
inlines = [AuthorInline]
fieldsets = (
(None, {
'fields': ('username', ('first_name', 'last_name'),
'email', 'password', 'groups', 'is_staff')
}),
)
class Media:
css = {
'all': [
'css/codenotes-admin.css',
]
}
def get_form(self, request, obj=None, **kwargs):
if obj is None:
return forms.AuthorCreation
else:
return forms.AuthorChange
admin.site.unregister(User)
admin.site.register(User, AuthorAdmin)
Again, the AuthorChangeForm correctly displays all the fields, but AuthorCreationForm only displays the username, password1, and password2 fields (plus the inline forms, which works fine on both).
I assume the problem is with the fieldsets, but I can't figure it out from the docs.
I figured out the solution. The problem was, as I suspected, the fieldsets. It turns out that the UserAdmin class inherits has TWO fieldsets that need to be overridden, fieldsets and add_fieldsets. I didn't see this mentioned anywhere in the docs (maybe I just missed it); I had to dig through the source to find it. As the name suggests, add_fieldsets is used when adding a new user. The following admin class works as expected:
admin.py
class AuthorAdmin(UserAdmin):
"""Admin class for creating and managing Authors"""
inlines = [AuthorInline]
fieldsets = (
(None, {
'fields': ('username', ('first_name', 'last_name'),
'email', 'password', 'groups', 'is_staff')
}),
)
add_fieldsets = (
(None, {
'fields': ('username', 'password1', 'password2',
('first_name', 'last_name'),
'email', 'groups', 'is_staff'),
}),
)
class Media:
css = {
'all': [
'css/codenotes-admin.css',
]
}
def get_form(self, request, obj=None, **kwargs):
if obj is None:
return forms.AuthorCreation
else:
return forms.AuthorChange
admin.site.unregister(User)
admin.site.register(User, AuthorAdmin)
From the Django doc:
class UserCreationForm¶ A ModelForm for creating a new user.
It has three fields: username (from the user model), password1, and
password2. It verifies that password1 and password2 match, validates
the password using validate_password(), and sets the user’s password
using set_password().
So it seems you have to create the extra fields yourself like this:
class AuthorCreation(UserCreationForm):
first_name = forms.CharField(required=True, label="First Name")
... etc ...
class Meta:
model = User
fields = ('username', 'password1', 'password2',
'first_name', 'last_name', 'email', 'groups', 'is_staff')

django admin: adding a new object as a foriegn key child in admin interface

I have a custom user object GameUser, a profile UserInfo that attaches to each user with information, and a Weapon model that each profile gets associated to, but can only have one at a time.
I want to be able to look up and existing GameUser in my admin interface and, in the change form, have the option to create an associate a new Weapon to that UserInfo profile.
Here's my models:
class GameUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField()
# ...etc
class UserInfo(models.Model):
first = models.CharField(max_length=30)
last = models.CharField(max_length=30)
# ...etc
# relations
user = models.OneToOneField(GameUser)
weapon = models.ForeignKey('Weapon', null=True)
class Weapon(models.Model):
name = models.CharField(max_length=20)
# ...etc
And my admin.py:
class GameUserChangeForm(forms.ModelForm):
password = ReadOnlyPasswordHashField()
class Meta:
model = GameUser
fields = ('email', 'password')
def clean_password(self):
return self.initial["password"]
class GameUserAdmin(UserAdmin):
form = GameUserChangeForm
list_display = ('email', 'is_admin')
list_filter = ('is_admin',)
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Permissions', {'fields': ('is_admin',)}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2')}
),
)
search_fields = ('email',)
ordering = ('email',)
filter_horizontal = ()
class UserInfoAdmin(admin.ModelAdmin):
fieldsets = [
('Personal Information', {'fields': [
'first', 'last']
}),
# ... etc
]
list_display = ('first', 'last')
search_fields = ['city', 'state']
admin.site.register(UserInfo, UserInfoAdmin)
admin.site.register(GameUser, GameUserAdmin)
If there is a Weapon associated with that GameInfo, I'd like to display it there inline. If not, I'd like to be able to create a new Weapon object for that GameInfo and set its fields.
I should mention I'm not married to Weapon being a ForiegnKey - it could certainly be a OneToOneField as well if that makes it easier.
What is the right way for me to do this in Django?

Adding extra fields to UserAdmin

i have this custom class
class CustomUserAdmin(UserAdmin):
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'email', 'password1', 'password2', 'location')}
),
)
fieldsets = (
(None, {'fields': ('username', 'password')}),
(('Personal info'), {'fields': ('first_name', 'last_name', 'email', 'location')}),
(('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', 'user_permissions')}),
(('Important dates'), {'fields': ('last_login', 'date_joined')}),
(('Groups'), {'fields': ('groups',)}),
)
#UserAdmin.list_display += ('location',)
add_form = MyUserCreationForm
form = MyUserChangeForm
It works fine, untill i uncomment this line
UserAdmin.list_display += ('location',)
then it gives me this error:
CustomUserAdmin.list_display[5], 'location' is not a callable or an attribute of 'CustomUserAdmin' or found in the model 'User'.
any help?
[Edit]
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class UserProfile(models.Model):
user = models.OneToOneField(User)
location = models.CharField(max_length=30)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
You are not going to modify UserAdmin right?
Supposing that location is an actual field of CustomUser, try to use
list_display = UserAdmin.list_display + ('location',)
EDIT: simpler answer
Use the standard django way to show custom things in the list_display:
class CustomUserAdmin(UserAdmin):
# other things
def user_location(self, u):
try:
return u.get_profile().location
except:
return ''
user_location.short_description = 'Location'
list_display = UserAdmin.list_display + ('user_location',)
EDIT: more info
Anyway, if you are extending the UserForm just for the sake of adding the profile fields, you should look into this link: http://www.thenestedfloat.com/articles/displaying-custom-user-profile-fields-in-djangos-admin/index.html to take advantages of inlines and avoid recreating the whole Form from scratch.

Categories