web-dev-qa-db-fra.com

Comment changer le fichier Django Admin Filtre pour utiliser une liste déroulante au lieu de la liste?

Si, pour un champ que vous souhaitez filtrer, vous avez plus de 10 valeurs, la barre latérale filtrante commence à être laide et plus difficile à utiliser.

Je cherche une solution pour remplacer le <li> Avec une sélection déroulante (Combobox) ou quelque chose de similaire qui résoudra le même problème.

40
sorin

Merci @Beholderrk, @gediminas et @ jk-Laiho! J'ai emballé cela dans une - application réutilisable .

Installer:

pip install Django-admin-list-filter-dropdown

Activer dans settings.py:

INSTALLED_APPS = (
    ...
    'Django_admin_listfilter_dropdown',
    ...
)

Utiliser dans admin.py:

from Django_admin_listfilter_dropdown.filters import (
    DropdownFilter, ChoiceDropdownFilter, RelatedDropdownFilter
)

class EntityAdmin(admin.ModelAdmin):
    ...
    list_filter = (
        # for ordinary fields
        ('a_charfield', DropdownFilter),
        # for choice fields
        ('a_choicefield', ChoiceDropdownFilter),
        # for related fields
        ('a_foreignkey_field', RelatedDropdownFilter),
    )

Voici à quoi ça ressemble:

Screenshot of dropdown list filter

39
mrts

Je ne peux pas commenter les réponses, donc je vais ajouter à la réponse de Beholderrk ici.

  1. créez un nouveau modèle appelé dropdown_filter.html ou similaire
  2. copier le code de filtre.html de FeincMS en dropdown_filter.html
  3. créez une nouvelle classe de filtres dans filters.py:

    from Django.contrib.admin.filters import AllValuesFieldListFilter
    
    class DropdownFilter(AllValuesFieldListFilter):
        template = 'admin/dropdown_filter.html'
    
  4. vous pouvez maintenant utiliser ce filtre dans votre classe d'administration:

    class SomeAdmin(admin.ModelAdmin):
        # ...
        list_filter = (('country', DropdownFilter),)
    

Fonctionne très bien!

33
Gediminas

Utiliser filter.html de FeincMS

{% load i18n %}
<script type="text/javascript">var go_from_select = function(opt) { window.location = window.location.pathname + opt };</script>
<h3>{{ title }}</h3>
<ul class="admin-filter-{{ title|cut:' ' }}">
{% if choices|slice:"4:" %}
    <li>
    <select style="width: 95%;"
        onchange="go_from_select(this.options[this.selectedIndex].value)">
    {% for choice in choices %}
        <option{% if choice.selected %} selected="selected"{% endif %}
         value="{{ choice.query_string|iriencode }}">{{ choice.display }}</option>
    {% endfor %}
    </select>
    </li>
{% else %}

    {% for choice in choices %}
            <li{% if choice.selected %} class="selected"{% endif %}>
            <a href="{{ choice.query_string|iriencode }}">{{ choice.display }}</a></li>
    {% endfor %}

{% endif %}
</ul>
29
beholderrk

Vous pouvez copier les modèles d'administration de l'installation Django Installation dans votre dossier Modèles/administrateurs de votre projet.

Ensuite, vous devrez faire l'une des 2 choses dans les formulaires ou les modèles que vous souhaitez afficher vos sorties dans:

  1. Si vous travaillez avec un formulaire, vous souhaitez que les choix de la liste soient publiés dans une base de données, vous le feriez dans votre modèle.py, sur le terrain que vous avez vos choix, y mettez-le comme suit:

    choice = forms.IntegerField(widget=forms.Select(choices=CHOICES))
    
  2. S'il est juste d'afficher sur une page, vous allez sortir sur une étiquette de modèle quelque chose comme ceci:

    <select>
      {% for choices in object.details.all %}
        <option> {{ object.choice }} </option>
      {% endfor %}
    </select>
    
2
Afrowave

http://djangosuit.com/ propose également des fichiers déroulants pour les filtres de liste.

2
user3061675

La meilleure solution consiste à créer un nouveau modèle dans admin/filter.html Et implémentez le code HTML suggéré par @Beholderrk. Je viens de la mettre en œuvre pour un client et ça marche génial.

Problème avec DropdownFilter and RelatedDropdownFilter Est-ce qu'il perd l'affichage approprié. Au lieu des chaînes traduites pour Charfield(choices=xxx), il montrera True, False et ainsi de suite.

0
Özer S.

Pourriez-vous s'il vous plaît donner un exemple complet. Cela montre comme avant. Voici mon code

from Django.contrib import admin
from pages.models import Post, Device, DeviceType, DeviceModel, Ipaddress, DeviceGroup, Location,Department,Comment
from Django_admin_listfilter_dropdown.filters import DropdownFilter, RelatedDropdownFilter


class CommentInline(admin.TabularInline):
    model = Comment

class IpaddressAdmin(admin.ModelAdmin):
        prepopulated_fields = {'slug': ('ipaddress',)}
#        model=Ipaddress

        search_fields = ['ipaddress', ]
#     
        list_display = ('ipaddress', 'machinename', 'user', 'department','location',)
        list_filter = (
        ('user', DropdownFilter),
        ('department', RelatedDropdownFilter),
        ('location', RelatedDropdownFilter),

    )

Voici la capture d'écran enter image description here

0
Rana