I am trying to to add a search to my model admin list page using the following Model and ModelAdmin classes:
models.py
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User)
country = CountryField(blank=True, null=True)
admin.py
from django.contrib import admin
from models import UserProfile
class UserProfileAdmin(admin.ModelAdmin):
list_display = ('user','country')
search_fields = ['user']
But I get the following error while trying to access the UserProfile in admin panel:
at /admin/profiles/userprofile/ Related Field has invalid
lookup: icontains
I have also tried the following:
search_fields = ['user_username']
And
search_fields = ['user_name']
def user_name(self,obj):
return obj.user.username
Any solutions?
Try using user__username, according to the lookup API “follow” notation.
Related
So I was trying to add an imagefield in my model using the UserModel, so I made this models
from django.contrib.auth.models import User
from django.db import models
class ProfileImage(models.Model):
user = models.OneToOneField(User,
on_delete=models.CASCADE,
editable=False)
avatar = models.ImageField()
def user_avatar(self):
return self.profileimage.avatar
User.add_to_class('user_avatar', user_avatar)
And I made an admin to see the imagefield in the users,
admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
# Register your models here.
UserAdmin.fieldsets += ('Custom fields set', {'fields': ('user_avatar',)}),
I dont kno what is wrong with my code, when I open a user to see the image field and , does anyone know what is the problem?
In admin fields and fieldsets expects you to list actual columns in the database. user_avatar is a function you've written so you can't list it as a field on the User model because it doesn't exist in that table.
Make a more generic model for all types of user information, not just an image, like this;
class Profile(models.Model):
"""
Profile model
"""
user = models.OneToOneField(
verbose_name=_('User'),
to=settings.AUTH_USER_MODEL,
related_name='profile',
on_delete=models.CASCADE
)
avatar = models.ImageField()
Then you can access the avatar with request.user.profile.avatar or in your admin register your Profile model as an inline to the User;
from django.contrib import admin
from django.contrib.auth import get_user_model
from myapp.accounts.models import Profile
User = get_user_model()
class ProfileInline(admin.StackedInline):
model = Profile
max_num = 1
can_delete = False
class MyUserAdmin(admin.UserAdmin):
inlines = [ProfileInline]
# unregister old user admin
admin.site.unregister(User)
# register new user admin that includes a UserProfile
admin.site.register(User, MyUserAdmin)
How can i make a custom search function in django admin. I want to search all fields of the database tables and to find and retrieve the matches.
Is it possible?
Lets take an example of custom User models with below fields,
app_name/models.py
from django.contrib.auth.models import AbstractBaseUser
class User(AbstractBaseUser):
first_name = models.CharField(max_length=50)
middle_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField(max_length=100)
username = models.CharField(max_length=100)
Now the admin for this models would be,
app_name/admin.py
from django.contrib import admin
from app_name.models import User
class UserAdmin(admin.ModelAdmin):
search_fields = User._meta.get_all_field_names()
admin.site.register(User, UserAdmin)
User._meta.get_all_field_names() will return you a list of all the fields of User model.
I have a Django project hosted on heroku
I added a new slug field to model
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=30)
slug = models.SlugField(unique=True)
def __unicode__(self):
return self.name
migrated it using south on heroku. Checked the heroku postgresDB as well for added field. All fine.
Opened Admin. No slug field showing...
added slug to fields[] in admin.py. Still not showing. Here is admin.py
from django.contrib import admin
from models import Category
class CategoryAdmin(admin.ModelAdmin):
fields = ('name', 'slug')
admin.site.register(Category, CategoryAdmin).
I even did a heroku restart... No change.
What can be done to show it ?
Try to use list_display like following:
from django.contrib import admin
from models import Category
class CategoryAdmin(admin.ModelAdmin):
fields = ('name', 'slug')
#list of fields to display in django admin
list_display = ['id', 'name', 'slug']
#if you want django admin to show the search bar, just add this line
search_fields = ['name', 'slug']
#to define model data list ordering
ordering = ('id','name')
admin.site.register(Category, CategoryAdmin).
Just in case someone ever faces this scenario
My admin classes were inheriting from UserAdmin, when they should have been inheriting from admin.ModelAdmin.
I had to change
class Model1(UserAdmin):
....
to
class Model1(admin.ModelAdmin):
....
I see the solution in here Django Website: https://docs.djangoproject.com/en/3.2/ref/models/fields/#editable, use fields's editable property.
editable
Field.editable
If False, the field will not be displayed in
the admin or any other ModelForm. They are also skipped during model
validation. Default is True.
I have posted a png image before, but I don't know how to display it.
I have the following in my models.py:
from django.db import models
class LabName(models.Model):
labsname=models.CharField(max_length=30)
def __unicode__(self):
return self.labsname
class ComponentDescription(models.Model):
lab_Title=models.ForeignKey('Labname')
component_Name = models.CharField(max_length=30)
description = models.CharField(max_length=20)
purchased_Date = models.DateField()
status = models.CharField(max_length=30)
to_Do = models.CharField(max_length=30,blank=True)
remarks = models.CharField(max_length=30)
def __unicode__(self):
return self.component
I have the following in my admin.py:
from django.contrib import admin
from Lab_inventory.models import ComponentDescription,LabName
class ComponentDescriptionAdmin(admin.ModelAdmin):
list_display= ('lab_Title','component_Name','description','purchased_Date','status','to_Do','remarks')
list_filter=('lab_Title','status','purchased_Date')
admin.site.register(LabName)
admin.site.register(ComponentDescription,ComponentDescriptionAdmin)
What I want is to display the fields under the component description to be displayed under the lab title(the fields related to each lab title by should be displayed under that lab name)
What you are doing with list_display and list_filter pertain to the list that is shown in the admin screen where the list of LabName objects are listed.
Assuming one LabName has one-to-many ComponentDescription entities, you need Django's InlineModelAdmin to display the list of ComponentDescription objects belonging to LabName within the admin page for a specific LabName entity. The code would be of the following structure:
from django.contrib import admin
from Lab_inventory.models import ComponentDescription,LabName
class ComponentDescriptionInline(admin.TabularInline):
model = ComponentDescription
class LabNameAdmin(admin.ModelAdmin):
inlines = [
ComponentDescriptionInline,
]
admin.site.register(LabName, LabNameAdmin)
where TabularInline is a subclass of the generic InlineModelAdmin.
My purpose is to see at the admin site only user name, email and phone number.
I've create UserProfile by extending User model:
model.py
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
name = models.CharField(max_length=50, null=True,blank=True)
address = models.CharField(max_length=50, null=True,blank=True)
phone = models.CharField(max_length=20, null=True,blank=True)
country = models.CharField(max_length=20, null=True,blank=True)
state = models.CharField(max_length=20, null=True,blank=True)
zip = models.CharField(max_length=10, null=True,blank=True)
code = models.CharField(max_length=40, null=True)
def user_email(self):
return self.user.email
admin.py
from myApp.models import UserProfile
from django.contrib import admin
class UserProfileAdmin(admin.ModelAdmin):
fields = ('name','phone',)
list_display = ('name','user_email',)
admin.site.register(UserProfile, UserProfileAdmin)
so on the list_display it works, I can see only the columns I've chosen, but when I add 'user_email' ( fields = ('name','user_email', 'phone',) )to fields I get when I try to go to admin site:
'UserProfileAdmin.fields' refers to field 'user_email' that is missing from the form.
Fields on a related model use two underscores. Dunno if it'll work in the admin though.
list_display = ('name','user__email',)
Just because I recently used it and you maybe want this, too: If you wan't to add an inline admin to the "User" admin page in Django you can do this (at least in Django 1.3) by doing:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from models import UserProfile
class UserProfileInlineAdmin(admin.StackedInline):
model = UserProfile
class MyUserAdmin(UserAdmin):
inlines = [ UserProfileInlineAdmin ]
admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)
You can't put editable fields from a related model into an admin form, without using inlines. You can show the field as a readonly value: just add it to readonly_fields.