Django Admin: упорядочение отношений ForeignKey и ManyToManyField, ссылающихся на пользователя
У меня есть приложение, которое использует Django UserProfile
для расширения встроенной модели Django User
. Выглядит немного как:
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
Я добавил новый класс в свою модель:
class Team(models.Model):
name = models.CharField(max_length=128)
manager = models.ForeignKey(User, related_name='manager')
members = models.ManyToManyField(User, blank=True)
И он зарегистрирован в Admin:
class TeamAdmin(admin.ModelAdmin):
list_display = ('name', 'manager')
admin.site.register(Team, TeamAdmin)
Увы, в интерфейсе admin, когда я иду, чтобы выбрать менеджера из раскрывающегося списка или установить членов команды через поле множественного выбора, они упорядочиваются с помощью числового идентификатора пользователя. Для жизни меня я не могу понять, как получить эти сортировки.
У меня есть аналогичный класс:
class Meta:
ordering = ['name']
Это отлично работает! Но я не "владею" классом User
, и когда я пробую этот трюк в UserAdmin
:
class Meta:
ordering = ['username']
Я получаю:
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
тоже не работает. Я мог бы указать, например image_url_s
, если захочу., как я могу сообщить администратору отсортировать списки пользователей username
? Спасибо!
Ответы
Ответ 1
Одним из способов было бы определить пользовательскую форму для использования в вашей модели Team в администраторе и переопределить поле manager
, чтобы использовать набор запросов с правильным порядком:
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
Ответ 2
Это
class Meta:
ordering = ['username']
должен быть
ordering = ['user__username']
если это в вашем классе adminProfile. Это остановит исключение, но я не думаю, что это поможет вам.
Заказ модели User по описанию довольно сложный, но см. http://code.djangoproject.com/ticket/6089#comment:8 для решения.
Ответ 3
Это может быть опасно по какой-то причине, но это можно сделать в одной строке в файле проекта models.py
:
User._meta.ordering=["username"]
Ответ 4
Для меня единственным рабочим решением было использование Прокси-модели. Как указано в документации, вы можете создавать собственные прокси-модели для даже встроенных моделей и настраивать что-либо вроде обычных моделей:
class OrderedUser(User):
class Meta:
proxy = True
ordering = ["username"]
def __str__(self):
return '%s %s' % (self.first_name, self.last_name)
После этого в вашей модели просто измените Foreign Key на:
user = models.OneToOneField(OrderedUser, unique=True)
или даже более подходящий
user = models.OneToOneField(OrderedUser, unique = True, parent_link = True)