16π
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)
6π
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
- [Django]-Django β SQL bulk get_or_create possible?
- [Django]-Is this the right way to do dependency injection in Django?
- [Django]-Changing a project name in django
3π
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
- [Django]-Django: How to format a DateField's date representation?
- [Django]-Django-reversion and related model
- [Django]-Django β "Incorrect type. Expected pk value, received str" error
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'
- [Django]-How does one make logging color in Django/Google App Engine?
- [Django]-ForeignKey to abstract class (generic relations)
- [Django]-Django Queryset with year(date) = '2010'
0π
I had the same problem and I had to extend @Todor βs solution for many models and different apps.
In the end, it was better to override the default AdminSite and hook on register to customize the User form fields.
from django.contrib import admin
from django.contrib.admin import ModelAdmin
from django.contrib.auth import get_user_model
def user_admin_str(instance: get_user_model()) -> str:
return f"{instance.last_name}-chan"
def formfield_for_foreignkey(self, db_field, request, **kwargs):
field = super(ModelAdmin, self).formfield_for_foreignkey(
db_field, request, **kwargs)
if isinstance(db_field.related_model(), get_user_model()):
field.label_from_instance = user_admin_str
return field
def formfield_for_manytomany(self, db_field, request, **kwargs):
field = super(ModelAdmin, self).formfield_for_manytomany(
db_field, request, **kwargs)
if isinstance(db_field.related_model(), get_user_model()):
field.label_from_instance = user_admin_str
return field
class CustomAdminSite(admin.AdminSite):
def register(self, model_or_iterable, admin_class=None, **options):
setattr(admin_class, "formfield_for_foreignkey",
formfield_for_foreignkey)
setattr(admin_class, "formfield_for_manytomany",
formfield_for_manytomany)
super().register(model_or_iterable, admin_class=admin_class, **options)
No need to modify every ModelAdmin
then.
- [Django]-Why does django run everything twice?
- [Django]-Adding css class to field on validation error in django
- [Django]-Macros in django templates