2009-09-24 16 views
18

Tengo una aplicación que utiliza el UserProfile de Django para ampliar el modelo Django User incorporado. Ve un poco como:Administrador de Django: Pedido de ForeignKey y relaciones ManyToManyField que hace referencia al usuario

class UserProfile(models.Model): 
    user = models.ForeignKey(User, unique=True) 
    # Local Stuff 
    image_url_s = models.CharField(max_length=128, blank=True) 
    image_url_m = models.CharField(max_length=128, blank=True) 

    # Admin 
    class Admin: pass 

he añadido una nueva clase de mi modelo:

class Team(models.Model): 
    name = models.CharField(max_length=128) 
    manager = models.ForeignKey(User, related_name='manager') 
    members = models.ManyToManyField(User, blank=True) 

Y se ha registrado en el administrador:

class TeamAdmin(admin.ModelAdmin): 
    list_display = ('name', 'manager') 

admin.site.register(Team, TeamAdmin) 

Por desgracia, en el inteface de administración Cuando selecciono un administrador del cuadro desplegable o establezco a los miembros del equipo a través del campo de selección múltiple, el ID numérico del usuario lo ordena. Por mi vida, no puedo encontrar la manera de ordenarlos.

tengo una clase similar con:

class Meta: 
    ordering = ['name'] 

que funciona muy bien! Pero no "propia" la clase User, y cuando intento este truco en UserAdmin:

class Meta: 
    ordering = ['username'] 

me sale:

django.core.management.base.CommandError: One or more models did not validate: events.userprofile: "ordering" refers to "username", a field that doesn't exist.

user.username tampoco funciona. Podría especificar, como image_url_s si quisiera. . . ¿Cómo puedo decirle al administrador que ordene mis listas de usuarios por username? ¡Gracias!

Respuesta

24

Una forma sería definir un formulario personalizado a utilizar para su modelo de equipo en el admin, y anular el campo manager utilizar un conjunto de consultas con el orden correcto:

from django import forms 

class TeamForm(forms.ModelForm): 
    manager = forms.ModelChoiceField(queryset=User.objects.order_by('username')) 

    class Meta: 
     model = Team 

class TeamAdmin(admin.ModelAdmin): 
    list_display = ('name', 'manager') 
    form = TeamForm 
+0

Thanks, Daniel! – dannyman

+2

Desde django 1.8 también necesita 'fields = '__all __'' dentro de 'Class Meta'. – Flash

26

Este

class Meta: 
    ordering = ['username'] 

debería ser

ordering = ['user__username'] 

si está en su clase PerfilUsuario administrador. Eso detendrá la excepción, pero no creo que te ayude.

Ordenar el modelo de Usuario como usted describe es bastante complicado, pero vea http://code.djangoproject.com/ticket/6089#comment:8 para una solución.

3

esto podría ser peligroso, por alguna razón, pero esto se puede hacer en una sola línea en el archivo del proyecto models.py:

User._meta.ordering=["username"] 
1

Para mí, la única solución de trabajo fue utilizar Proxy Model.Como se indica en la documentación, puede crear modelos de proxy propios para modelos incluso incorporados y personalizar cualquier cosa como en modelos regulares:

class OrderedUser(User): 
    class Meta: 
     proxy = True 
     ordering = ["username"] 
    def __str__(self): 
     return '%s %s' % (self.first_name, self.last_name) 

Después de eso, en su modelo simplemente cambiar de clave externa a:

user = models.OneToOneField(OrderedUser, unique=True) 

o aún más adecuado

user = models.OneToOneField(OrderedUser, unique = True, parent_link = True) 
Cuestiones relacionadas