2016-06-28 18 views
9

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?

+1

È 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

+1

Posso creare un modello proxy per Utente, ma suppongo che devo usarlo come chiave esterna per tutti i modelli? – vicusbass

+1

Sì, dovrai farlo. – xtranophilist

risposta

3

È 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 
2

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' 
+1

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

3

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 
+1

Questa è una buona soluzione, ma richiede la definizione di un modello di amministrazione personalizzato per ogni modello. – jastr

9

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) 
+1

La classe utente di base Django ha quel decoratore, quindi, sul caricamento '__unicode__' è impostato su' __str__ '. Pertanto, sembra che dovremmo sovrascrivere '__unicode__' – jastr

+0

In realtà non è necessario sovrascrivere il metodo' __unicode__', per impedire l'override stiamo usando 'add_to_class' – Surajano