Django Admin: ordenamiento de las relaciones ForeignKey y ManyToManyField referencia a usuario
-
16-09-2019 - |
Pregunta
Tengo una aplicación que hace uso de UserProfile
de Django para extender el modelo User
incorporado en Django. Se ve un poco como:
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 voy a seleccionar un administrador de la caja desplegable, o los miembros del equipo conjunto a través del campo de selección múltiple, que son ordenados por el identificador numérico del usuario. Para la vida de mí, no puedo encontrar la manera de obtener estos ordenadas.
Tengo una clase similar con:
class Meta:
ordering = ['name']
Esto 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
no funciona bien. Podría especificar, como image_url_s
si quería. . . ¿Cómo puedo saber el administrador para ordenar mis listas de usuarios por username
? Gracias!
Solución
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
Otros consejos
Este
class Meta:
ordering = ['username']
debería ser
ordering = ['user__username']
si está en su clase PerfilUsuario administrador. Eso va a detener la excepción, pero no creo que le ayuda.
El ordenar el modelo de usuario que usted describe es bastante complicado, pero ve http: // código .djangoproject.com / entradas / 6089 # comentario:. 8 de una solución
Esto puede ser peligroso, por alguna razón, pero esto se puede hacer en una sola línea en el archivo models.py
de su proyecto:
User._meta.ordering=["username"]
Para mí, la única solución de trabajo era utilizar Proxy modelo. Como se indica en la documentación, puede crear modelos propios de proxy 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 acaba de cambiar de clave externa a:
user = models.OneToOneField(OrderedUser, unique=True)
o incluso más adecuado
user = models.OneToOneField(OrderedUser, unique = True, parent_link = True)