2016-06-28 13 views
9

Mam kilka modeli mających użytkownika jako klucz obcy. Lista użytkowników wyświetla nazwę użytkownika, ale chcę ją dostosować. Czy muszę przedłużyć model użytkownika za pomocą niestandardowego modelu i napisać własną funkcję __str__? Czy istnieje prostszy sposób? Nie sądzę, że można użyć wywołania dla zestawu pól, prawda?Jak zmienić reprezentację użytkownika w Django Admin, gdy jest używany jako klucz obcy?

+1

Możesz użyć niestandardowego administratora, takiego jak @dmitryro. Nie potrzebujesz narzędzi django-admin, aby osiągnąć to, o co prosiłeś. Jeśli chcesz pokazać coś innego niż nazwa użytkownika w innym miejscu, polecam używanie modeli proxy i zastępowanie metody __str__ zamiast tworzenia niestandardowego modelu użytkownika. – xtranophilist

+1

Mogę utworzyć model proxy dla użytkownika, ale chyba muszę go użyć jako klucz obcy dla wszystkich modeli? – vicusbass

+1

Tak, będziesz musiał. – xtranophilist

Odpowiedz

3

Można zmienić ciąg znaków reprezentujący domyślnego użytkownika Django, zastępując metodę User __unicode__. Dodaj poniższy kod gdzieś w swojej aplikacji, być może w 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

Załóżmy masz model podobny do tego

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) 

I chcesz pokazać e-mail użytkownika zamiast nazwy użytkownika lub identyfikatora użytkownika admin strona, można zrobić coś takiego

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

Pytanie dotyczy pytania o to, jak pole Użytkownik wygląda na innych obiektach, gdy Użytkownik jest obcym kluczem. Spowoduje to jedynie zmianę reprezentacji na stronie UserProfile. – jastr

3

ForeignKeys formularzy Django są reprezentowane przez ModelChoiceFields. Klasa ModelChoiceField ma metodę label_from_instance, która decyduje o renderowaniu wyboru. Aby zmienić tę reprezentację w panelu administracyjnym, musisz zmodyfikować to pole formularza.

Oto prosty przykład.

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

Jest to dobre rozwiązanie, ale wymaga zdefiniowania niestandardowego modelu administratora dla każdego modelu. – jastr

9

myślę __unicode__() metoda nie jest prawidłowe, należy użyć __str__() metody.

Dla Python 2.x, __str__() metoda zwróci str (bajty) i __unicode__() metoda zwróci unicode (tekst).

Instrukcja print i STR wbudowaną rozmowy __str__() celu ustalenia z czytelną reprezentację obiektu. Wbudowany unicode dzwoni __unicode__(), jeśli istnieje, i w inny sposób wraca do __str__() i dekoduje wynik z kodowaniem systemowym. Odwrotnie, klasa bazowa modelu automatycznie uzyskuje __str__() z __unicode__() przez kodowanie do UTF-8. read here complete

Ale w Python 3.x jest tylko __str__() nie __unicode__() metoda.

Django zapewnia prosty sposób definiowania __str__() i __unicode__() sposoby, które działają na Python 2 i 3: należy zdefiniować __str__() metoda przekazujących tekst i zastosować python_2_unicode_compatible() dekorator.

W języku Python 3 dekorator nie jest dostępny. W języku Python 2 definiuje on metody odpowiednie __unicode__() i __str__() (zastępując oryginalną metodę __str__()).

Oto przykład z dokumentacji Django.

from django.utils.encoding import python_2_unicode_compatible 

@python_2_unicode_compatible 
class MyClass(object): 
    def __str__(self): 
     return "Instance of my class" 

ROZWIĄZANIE: ozdobić w taki sam sposób, jak odbywa się powyżej swojej klasy i w models.py, dodać metodę, które zostaną dodane do modelu użytkownika.

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

Klasa użytkownika Django ma ten dekorator, więc przy ładowaniu '__unicode__' jest ustawiona na' __str__ '. Dlatego wygląda na to, że będziemy musieli przesłonić '__unicode__' – jastr

+0

W rzeczywistości nie ma potrzeby przesłonięcia metody __unicode__, aby zapobiec nadpisywaniu używamy' add_to_class' – Surajano