Ho alcuni modelli con Utente come chiave esterna. L'elenco utenti sta visualizzando il nome utente, ma mi piacerebbe personalizzarlo. Devo estendere il modello utente con un modello personalizzato e scrivere la mia funzione __str__
? C'è un modo più semplice? Non penso che tu possa usare un callable per fieldset, giusto?Come cambiare la rappresentazione utente in Django Admin quando usato come chiave esterna?
risposta
È possibile modificare la rappresentazione della stringa dell'utente predefinito Django ignorando il metodo Utente __unicode__
. Aggiungere il codice qui sotto qualche parte nella tua app, magari 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
Si supponga di avere un modello come questo
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)
e si desidera mostrare e-mail dell'utente, invece di un nome utente o ID utente in Admin pagina, quindi si può fare qualcosa di simile
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'
La domanda è chiedere come il campo Utente cerca su altri oggetti quando Utente è una chiave esterna. Questo cambierà solo la rappresentazione nella pagina UserProfile. – jastr
ForeignKeys
in forme Django sono rappresentati da ModelChoiceFields
. La classe ModelChoiceField
ha un metodo label_from_instance
, che decide come eseguire il rendering della scelta. Pertanto, per modificare questa rappresentazione nell'Amministratore, è necessario modificare questo campo modulo.
Ecco un semplice esempio.
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
Questa è una buona soluzione, ma richiede la definizione di un modello di amministrazione personalizzato per ogni modello. – jastr
Penso __unicode__()
metodo non è quella giusta, è necessario utilizzare __str__()
metodo.
Per Python 2.x
, __str__()
il metodo restituirà str (byte) e il metodo __unicode__()
restituirà unicode (testo).
Il comunicato stampa e il built-in str chiamata
__str__()
per determinare rappresentazione leggibile di un oggetto. L'unicode integrato chiama__unicode__()
se esiste, e altrimenti torna a__str__()
e decodifica il risultato con la codifica di sistema. Al contrario, la classe base del modello deriva automaticamente__str__()
da__unicode__()
mediante la codifica in UTF-8. read here complete
Ma in Python 3.x
c'è solo __str__()
, nessun metodo __unicode__()
.
Django fornisce un modo semplice per definire
__str__()
e__unicode__()
metodi che funzionano su Python 2 e 3: è necessario definire un testo di ritorno__str__()
metodo e di applicare il decoratore python_2_unicode_compatible() .Su Python 3, il decoratore è un non-op. In Python 2, definisce appropriati metodi
__unicode__()
e__str__()
(sostituendo il metodo__str__()
originalenel processo).
Ecco un esempio di 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"
SOLUZIONE: Decorare allo stesso modo, come fatto in precedenza per la vostra classe e in models.py
, aggiungere un metodo che sarà ottenere aggiunto al modello User.
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)
La classe utente di base Django ha quel decoratore, quindi, sul caricamento '__unicode__' è impostato su' __str__ '. Pertanto, sembra che dovremmo sovrascrivere '__unicode__' – jastr
In realtà non è necessario sovrascrivere il metodo' __unicode__', per impedire l'override stiamo usando 'add_to_class' – Surajano
È possibile utilizzare l'amministratore utente personalizzato, come @dmitryro. Non avrai bisogno di django-admin-tools per realizzare ciò che hai chiesto. Se hai bisogno di mostrare qualcosa di diverso dal nome utente anche altrove, ti consigliamo di utilizzare modelli proxy e di eseguire l'override del metodo __str__, creando invece un modello utente personalizzato. – xtranophilist
Posso creare un modello proxy per Utente, ma suppongo che devo usarlo come chiave esterna per tutti i modelli? – vicusbass
Sì, dovrai farlo. – xtranophilist