Django admin, foreign key field in list_editable - django

Hi fellow django users,
How can I add a field from a related object in the list_editable admin property?
# models.py
class Order(Model):
reference = CharField(max_length=25)
class Product(Model):
name = CharField(max_length=50)
order = ForeignKey(Order)
# admin.py
class ProductAdmin:
list_display = ('name', 'order_reference')
list_editable = ('name', 'order__reference') # <--- THIS !
def order_reference(self, obj):
return obj.order.reference
I tried it this way, but it won't work. I also tried to add a property in the Product class, but nope, it won't work either. Any clue?
Thanks.

From the documentation:
list_editable interacts with a couple of other options in particular
ways; you should note the following rules:
Any field in list_editable must also be in list_display. You can't edit a field that's not displayed!
The same field can't be listed in both list_editable and list_display_links -- a field can't be both a form and a link.
You'll get a validation error if either of these rules are broken.
Notice that you use *order_reference* and *order__reference* in list_display and list_editable, respectively. So in short, I don't think you can do this easily. If you want to have inspiration, you could check out the implementation of pageadmin.py in django-cms, but it's NOT straightforward!!

Related

Django's list_select_related does not show foreign key's attributes

Basically I am trying to have the attributes of a foreign key available both in the list_display and in the admin editor. However, even using the list_select_related (I have also tried modifying the queryset with the select_related method) the foreign key attributes do not appear in any of the mentioned admin screens. Toy example:
class BookAdmin (admin.ModelAdmin):
list_select_related = ('author',)
Where the book model has a OneToOne relationship with author, and author has some attributes (first_name, last_name, etc.) that I want to display in the admin site. Am I forgetting something? I know I could do lookups to list and inlines to edit, but it doesn't seem like a very optimal solution ...
Thank you very much!
For your particular case I think you are looking to use the following Admin class properties:
list_display Docs: Using your example, if you want to display the name of the book and its author name in the admin:
class BookAdmin (admin.ModelAdmin):
list_display = ('name', 'author',)
search_fields Docs Now if you also want to be able to filter by book name as well as their author names:
class BookAdmin (admin.ModelAdmin):
list_display = ('name', 'author',)
list_filter = ['name', 'author__name']

How to extend Django Admin model readonly_fields without having to specify all model fields (but still see them)

In a Django Admin model, if I don't provide a fields or readonly_fields tuple, it will display the model's default fields.
But if I want to add a calculated field, like:
class SomeModelAdmin(admin.ModelAdmin):
readonly_fields = ('get_calculated_field',)
fields = ('get_calculated_field',)
then it will override all its fields and just display this one.
Is there a way to extend the SomeModel fields and add the calculated field on top of that, so that all of the model's existing fields don't have to be added to the tuples?
Add only the readonly_fields setting (and not the fields setting). That will cause it to include all the default fields plus the calculated one:
class SomeModelAdmin(admin.ModelAdmin):
readonly_fields = ('get_calculated_field',)
# Note: no 'fields = ...' setting here

Django - Display User Email in User Profile Admin

This may be a very simple question, but I haven't been able to find it in SO.
I created a User Profile Model for additional user info via OnetoOneField. Now for the Admin of the User Profile Model, I want to display the email field found in the User model. I tried:
# models.py
def email(self):
return self.user.email
# admin.py
fieldsets = [
('', {'fields': [
...
'email',
...
]})
]
list_display = (
...
'email',
...
)
This worked for the list_display section, but for fieldsets, the following error popped up:
Unknown field(s) (email) specified for UserProfile. Check fields/fieldsets/exclude attributes of class UserProfileAdmin.
Is there a way to work around this? Thank you in advance!
From the documentation:
fields can contain values defined in readonly_fields to be displayed
as read-only.
If you add the name of a callable to fields, the same rule applies as
with the fields option: the callable must be listed in
readonly_fields.
So you need to add:
readonly_fields = ('email',)
to your model admin class, and then it will be available in the fieldset.
Put this
def email(self, obj):
return obj.user.email
in your admin class of userprofile and you will be able to use it in fieldsets.

list_display in admin behave nothing

This is my github repo Inout. I am learning django and i worked Very very simple django registration & login system.
My question is:
How to list all the usernames in admin using list_display. But nothing display in admin panel. May i know why ?
Inside my working code:
# models.py
username = models.OneToOneField(User)
first_name = models.CharField(max_length=100)
# admin.py
class SignupAdmin(admin.ModelAdmin):
list_display = ['username']
admin.site.register(Signup, SignupAdmin)
Information for you Reference :
if i am using list_filter in admin i can see all the username in the filter panel
Then if i am accessing this page http://127.0.0.1:8000/admin/system/signup/
Select signup to change
0 signups
And also if i am accessing this page http://127.0.0.1:8000/admin/frontend/profile/add/ i can see the drop down of username shows all the username i registered before.
What i missing ? or can somebody clone my repo and see yourself.
Are you sure it's not working correctly? list_display is supposed to take a tuple/list of fields and then display those fields as columns of the main table like in the picture shown below taken from the django admin documentation, where each entry in the main table has a username, email address, first name, last name, staff status. This would be created by
list_display = ['username', 'email', 'first_name', 'last_name', 'is_staff']
in a ModelAdmin for the built in User model (taken from django.contrib.auth.models). The side-column on the right side (with the label "Filter") is populated only when you define fields under list_filter.
Note if you only defined one field, and your model has a __unicode__ function that returns the username, you will not see a significant difference with just adding list_display = ('username',). I suggest you try list_display = ('username', 'first_name',). In this case, for every SignUp you will see two columns in the main table -- one with the username and one with the first_name.
EDIT
You have two errors.
First, you don't seem to have created any SignUp objects anywhere. Before the admin change list will display any entries, you must create some entries.
Second, your __unicode__ method of your SignUp model refers to non-existent fields (self.user is never defined -- in your SignUp class you used username = models.OneToOneField(User)
, hence you refer to it as username) and furthermore it doesn't return a unicode string as required.
Try:
def __unicode__(self):
if self.username:
return unicode(self.username)
then create some SignUp and then it will work. Again, the list_display part was working perfectly.

How to add the auto primary key into django's admin list_display

Is it possible to include the automatically created primary key into the list_display of the admin site?
I might also need to include that primary key into the links field on the display page.
Any idea?
Thanks in advance.
Yes, in the list_display field, you can add the pk field.
To make it linkable, you can use the list_display_links field
class MyModelAdmin(admin.ModelAdmin):
list_display = ('pk', 'name', 'email', ...) #You can use 'pk' or 'id'
list_display_links = ('pk', ) #the same here - 'pk' or 'id'
admin.register(MyModel, MyModelAdmin)
The automatically created primary key field works just like any other field, except that you don't have to specify it. Unless you've changed the name, this should be as simple as:
list_display = ['id', ...]
I haven't checked on whether or not the pk alias works everywhere that the admin expects field names.
UPDATE: the pk alias is accepted instead of id