Lepszy widżet pola ManyToMany dla administratorów Django

102

Uważam, że domyślny models.ManyToManyFieldwidżet Django Admin jest kłopotliwy w użyciu. Jest to element wyboru HTML i jeśli masz dużo obiektów z „innego” modelu, to jest całkiem niepraktyczne znalezienie „innych” obiektów, które chcesz powiązać z „tym” obiektem. A jeśli masz dużo obiektów z „innego” modelu, wydaje się, że nawet spowalnia renderowanie strony Admin.

Zdaję sobie sprawę, że mogę zbudować własny niestandardowy widżet administratora i zastosować go do mojego ManyToManyFieldswedług własnego uznania, ale czy są tam jakieś gotowe elementy, których mógłbym zamiast tego użyć? W moich snach wyobrażam sobie automatycznie uzupełniający się widget HTML do wprowadzania tekstu. Czy jest to w ogóle praktyczne / możliwe do zrobienia we frameworku administracyjnym Django?

Dzięki.

Chris W.
źródło

Odpowiedzi:

161

Spróbuj użyć filter_horizontalatrybutu w swojej klasie administratora, na przykład:

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

Jak wspomniano w dokumentacji , „dodanie ManyToManyField do tej listy spowoduje zamiast tego użycie sprytnego, dyskretnego interfejsu„ filtru ”JavaScript, który umożliwia wyszukiwanie w ramach opcji”. filter_verticalrobi to samo z nieco innym układem.

Blair
źródło
Wspaniały! To brzmi jak dokładnie to, czego szukam, spróbuję.
Chris W.
To działa Ale jak sprawić, by to pole było tylko do odczytu. Próbuję czytać only_fields = ('użytkownicy',). Ale jest pokazany w jednym wierszu oddzielonym przecinkiem. Chcę pokazać w
podziale
Martwiłem się, że będę musiał napisać własny widget, ale to jest idealne! Dziękuję za to! ; P
umat
7

możesz spróbować użyć surowego identyfikatora w panelu administracyjnym. oraz dokumentacja django: http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.raw_id_fields

jeśli szukasz czegoś z autouzupełnianiem, możesz potraktować to jako punkt wyjścia http://code.djangoproject.com/wiki/AutoCompleteSolutions

i na koniec bardzo uproszczony przykład wbudowany:

models.py

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

admin.py:

class SomeModelAdmin(admin.ModelAdmin):
    raw_id_fields = ("users",)
mrfunyon
źródło
3

Właściwie to nie bawiłem się tym, ale znalazłem tę obiecująco wyglądającą bibliotekę, do której odwołuje się gdzie indziej.

Wydaje się, że robi dokładnie to, czego chciałem. Zamiast wczytywać całą listę powiązanych obiektów (niezależnie od tego, ile ich jest!) I prezentować ci selektor do wybrania kilku z nich, tak jak to filter_horizontalrobi, przedstawia pole wyszukiwania / filtru i używa wywołań typeahead / autocomplete do pobierania wyników dynamicznie. Jest to świetne rozwiązanie w przypadku, gdy masz około 5000 użytkowników i chcesz wybrać 3 lub 4 z nich bez czekania na <option>pobranie i renderowanie elementów 5k .

Coderer
źródło