Um widget de campo ManyToMany de administrador Django melhor

101

Acho que o models.ManyToManyFieldwidget padrão do Django Admin é complicado de usar. É o elemento de seleção do HTML e se você tiver muitos objetos do "outro" modelo, então é pouco prático encontrar os "outros" objetos que deseja associar a "este" objeto. E se você tiver muitos objetos do modelo "outro", parece até mesmo retardar a renderização da página Admin.

Estou ciente de que posso construir meu próprio widget de administração personalizado e aplicá-lo ao meu ManyToManyFieldscomo achar adequado, mas há algum pré-criado que eu possa usar no lugar? Em meus sonhos, imagino um widget HTML de entrada de texto com preenchimento automático. Isso é prático / possível de fazer na estrutura de administração do Django?

Obrigado.

Chris W.
fonte

Respostas:

160

Tente usar o filter_horizontalatributo em sua classe de administrador, por exemplo:

class SomeModelAdmin(admin.ModelAdmin):
    filter_horizontal = ('users',)

Conforme mencionado na documentação , "adicionar um ManyToManyField a esta lista usará, em vez disso, uma interface de" filtro "inteligente e discreta de JavaScript que permite pesquisar nas opções". filter_verticalfaz a mesma coisa com um layout ligeiramente diferente.

Blair
fonte
Ótimo! Parece exatamente o que estou procurando, vou tentar.
Chris W.
Está funcionando, mas como fazer este campo somente leitura. Estou tentando ler only_fields = ('usuários',). Mas é mostrado em uma única linha separada por vírgula. Quero ser mostrado na quebra de linha ...
Varnan K
Eu estava preocupado se teria que escrever meu próprio widget, mas isso é perfeito! Obrigado por isso! ; P
umat
7

você pode tentar usar um id original no admin. e os documentos do django: http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.raw_id_fields

se você está procurando algo com preenchimento automático, você pode querer olhar para isso como um ponto de partida http://code.djangoproject.com/wiki/AutoCompleteSolutions

e, finalmente, um exemplo embutido muito simplista:

models.py

class SomeModel(models.Model):
    users = models.ManyToMany(User)

admin.py:

class SomeModelAdmin(admin.ModelAdmin):
    raw_id_fields = ("users",)
mrfunyon
fonte
3

Na verdade, não brinquei com ele, mas descobri que essa biblioteca de aparência promissora é referenciada em outro lugar.

Parece fazer exatamente o que eu queria. Em vez de carregar toda a lista de objetos relacionados (independentemente de quantos sejam!) E apresentar a você um seletor para selecionar alguns deles, como filter_horizontalfaz, apresenta uma caixa de pesquisa / filtro e usa chamadas de preenchimento automático / antecipado para recuperar os resultados dinamicamente. Isso é ótimo para o caso em que você tem talvez 5.000 usuários e deseja escolher 3 ou 4 deles sem esperar que 5k <option>elementos sejam baixados e renderizados.

Coderer
fonte
0

Esta é uma pergunta antiga, mas eu quero adicionar uma resposta aqui para as pessoas que acham isso exatamente como eu: essa situação é exatamente para o que os administradores inline do Django existem. Especificamente, eu uso TabularInlines com campos de id brutos para relações muitos-para-muitos que têm muitas opções.

https://docs.djangoproject.com/en/2.1/ref/contrib/admin/#django.contrib.admin.TabularInline

Kloddant
fonte