Pergunta

Eu tenho um aplicativo que faz uso de UserProfile do Django para estender o built-in Django modelo User. Parece um pouco 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

Eu adicionei uma nova classe para o meu modelo:

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

E ele é registrado no Administrador:

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

admin.site.register(Team, TeamAdmin)

Infelizmente, na inteface admin, quando vou para selecionar um gerente partir da caixa drop-down, ou membros da equipe definida através do campo multi-select, eles são ordenados pela numérico ID de usuário. Para a vida de mim, eu não consigo descobrir como obter esses ordenados.

Eu tenho uma classe semelhante com:

class Meta:
    ordering = ['name']

Isso funciona muito bem! Mas eu não "próprio" a classe User, e quando eu tente este truque em UserAdmin:

class Meta:
    ordering = ['username']

eu recebo:

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 não quer trabalhar. Eu poderia especificar, como image_url_s se eu quisesse. . . como posso dizer ao administrador para classificar minhas listas de usuários por username? Obrigado!

Foi útil?

Solução

Uma maneira seria definir um formulário personalizado para usar para o seu modelo de equipe do admin, e substituir o campo manager usar um queryset com a ordem correta:

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

Outras dicas

Este

class Meta:
    ordering = ['username']

deve ser

    ordering = ['user__username']

se é em sua classe admin UserProfile. Isso vai parar a exceção, mas eu não acho que ele ajuda você.

Como encomendar o modelo User como você descreve é ??bastante complicado, mas veja http: // código .djangoproject.com / ingressos / 6089 # comentário: 8. para uma solução

Isso pode ser perigoso, por algum motivo, mas isso pode ser feito em uma única linha no arquivo models.py do seu projeto:

User._meta.ordering=["username"]

Para mim, a única solução trabalho era usar Proxy modelo. Como indicado na documentação, você pode criar modelos próprios de proxy, mesmo para built-in modelos e personalizar qualquer coisa como em modelos regulares:

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

Depois disso, no seu modelo apenas mudar Chave estrangeira para:

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

ou até mais adequado

user = models.OneToOneField(OrderedUser, unique = True, parent_link = True)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top