Sunday, April 16, 2017

How to change User representation in Django Admin when used as Foreign Key?

Leave a Comment

I have a few models having User as Foreign Key. The User list is displaying the username, but I'd like to customize it. Do I have to extend the User model with a custom model and write my own __str__ function? Is there an easier way? I don't think you can use a callable for fieldset, right?

4 Answers

Answers 1

I think __unicode__() method is not the correct, you should use __str__() method.

For Python 2.x, __str__() method will return str(bytes) and __unicode__() method will return unicode (text).

The print statement and the str built-in call __str__() to determine the human-readable representation of an object. The unicode built-in calls __unicode__() if it exists, and otherwise falls back to __str__() and decodes the result with the system encoding. Conversely, the Model base class automatically derives __str__() from __unicode__() by encoding to UTF-8. read here complete

But in Python 3.x there is just __str__(), no __unicode__() method.

Django provides a simple way to define __str__() and __unicode__() methods that work on Python 2 and 3: you must define a __str__() method returning text and to apply the python_2_unicode_compatible() decorator.

On Python 3, the decorator is a no-op. On Python 2, it defines appropriate __unicode__() and __str__() methods (replacing the original __str__() method in the process).

Here is an example from django docs.

from django.utils.encoding import python_2_unicode_compatible  @python_2_unicode_compatible class MyClass(object):     def __str__(self):         return "Instance of my class" 

SOLUTION : Decorate in the same way, as done above for your Class and in models.py, add a method which will be get added to the User model.

from django.contrib.auth.models import User  def get_name(self):     return '{} {}'.format(self.first_name, self.last_name)  User.add_to_class("__str__", get_name) 

Answers 2

You can change the string representation of the Django default User by overriding the User __unicode__ method. Add the code below somewhere in your app, perhaps in models.py

def custom_user_display(self):     return self.email + ', ' self.first_name # write your representation here  User.add_to_class("__unicode__", custom_user_display) # override the __unicode__ method 

Answers 3

Assume you have a model like this

class UserProfile(models.Model):     user = models.OneToOneField(User, unique=True, verbose_name=_('user'), related_name='profile')     city = models.CharField(max_length=128, null=True, blank=True) 

And you want to show the user's email instead of username or userid in admin page, then you can do something like this

class UserProfileAdmin(admin.ModelAdmin):     list_display = ('get_user', 'city')      def get_user(self, obj):         return obj.user.email     get_user.short_description = 'User'     get_user.admin_order_field = 'user__id' 

Answers 4

ForeignKeys in Django forms are represented by ModelChoiceFields. The ModelChoiceField class has a label_from_instance method, which decides how to render the choice. So in order to change this representation in the Admin, you need to modify this form field.

Here is a simple example.

class MyModelAdmin(admin.ModelAdmin):     def formfield_for_foreignkey(self, db_field, request, **kwargs):         field = super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)         if db_field.name == "user":             field.label_from_instance = lambda u: "My Object #%i" % u.id         return field 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment