Подтвердить что ты не робот

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? Спасибо!

4b9b3361

Ответ 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)