Django-filter: Filter nach Django-Taggit (Anfrage)

Erstellt am 16. Aug. 2016  ·  11Kommentare  ·  Quelle: carltongibson/django-filter

Gemessen an den Sternen ist

Was halten Sie von einem Django-Taggit-Filter?

Das nächste, was ich dazu habe, ist:

tags = django_filters.ModelMultipleChoiceFilter(
        name='tags__name',
        to_field_name='name',
        conjoined=True,
        distinct=True,
        queryset=Tag.objects.all(),
    )

Aber ich kann die Groß-/Kleinschreibung nicht beachten (ein Filter für das Tag 'Test' sollte Ergebnisse mit dem Tag 'test' zurückgeben).

Hilfreichster Kommentar

Arbeitsbeispiel mit neuesten Bibliotheken:

from taggit.forms import TagField
from django_filters.views import FilterView

class TagFilter(django_filters.CharFilter):
    field_class = TagField

    def __init__(self, *args, **kwargs):
        kwargs.setdefault('lookup_expr', 'in')
        super().__init__(*args, **kwargs)


class MyFilter(django_filters.FilterSet):
    tags = TagFilter(field_name='tags__name')

    class Meta:
        model = MyModel

Alle 11 Kommentare

Wie würde sich das TaggitFilter von einem normalen ModelMultipleChoiceFilter ?

Auch ich bin ziemlich sicher , könnten wir hinzufügen lookup_expr Unterstützung hier einfach durch die Feldnamen mit der Lookup - Beitritt.

Bei ModelMultipleChoiceFilter die URL field_name=tag1&field_name=tag2 , aber es kann eine beträchtliche Anzahl von Tags geben, wodurch die URL sehr lang wird. Nicht ideal für eine URL, die beispielsweise geteilt werden könnte.

Tags werden von django-taggit unter Verwendung eines Regelsatzes verarbeitet , der es ermöglicht, einen einzigen String zu übergeben, der alle Tags enthält.

Unabhängig davon wäre lookup_expr in ModelMultipleChoiceFilter definitiv hilfreich!

Ein kurzer Blick zeigt, dass Sie Taggits TagsField . Dies würde Ihnen ihr CSV-Parsing-Verhalten geben.

class TagsFilter(CharFilter):
    field_class = taggit.forms.TagsField

    def __init__(self, *args, **kwargs):
        kwargs.setdefault('lookup_expr', 'in')


class MyFilterSet(FilterSet):
    tags = TagsFilter(name='tags__name')

    class Meta:
        model = MyModel
GET http://localhost/api/my-model?tags=a,b,c,d

Der Vorbehalt hier ist, dass dies eine in Suche verwendet, was nicht die Lösung ist, nach der Sie suchen.

Ich bin mehr oder weniger der Meinung, keinen bestimmten Filter für Django Taggit hinzuzufügen, auch wenn es ein großartiges Paket sein mag.

Letztendlich ist das Erstellen von Filtern auf Projektebene nicht so schwer. Ein anständiger Kern wäre ein langer Weg. (Google ist großartig für diese.)

Gerne schaue ich mir eine A+-Pull-Anfrage an, wenn eine auftaucht, aber ansonsten schließe ich dies als außerhalb des Umfangs.

OK Fair genug. Was ist mit der Unterstützung für lookup_expr in ModelMultipleChoiceFilter ?

@stantond Freue mich über eine PR. _Zeig mir den Cödz_ 😀

Ich wünschte, ich könnte - leider bin ich kein erfahrener Entwickler, sondern eine fummelige PM!

+1

Arbeitsbeispiel mit neuesten Bibliotheken:

from taggit.forms import TagField
from django_filters.views import FilterView

class TagFilter(django_filters.CharFilter):
    field_class = TagField

    def __init__(self, *args, **kwargs):
        kwargs.setdefault('lookup_expr', 'in')
        super().__init__(*args, **kwargs)


class MyFilter(django_filters.FilterSet):
    tags = TagFilter(field_name='tags__name')

    class Meta:
        model = MyModel

Verwenden Sie das Feld slug des Tags anstelle des Felds name , um die Groß-/Kleinschreibung zu beachten. Taggit schreibt die Slugs standardmäßig in Kleinbuchstaben.

Beachten Sie, dass wir die Lösung in https://github.com/carltongibson/django-filter/issues/460#issuecomment -507218839 um ein benutzerdefiniertes Feld erweitern können, wenn wir die Filterung durch ein einzelnes Tag unterstützen möchten, das ein oder mehrere Leerzeichen enthält.

from django import forms
from django.utils.translation import gettext as _

from taggit.utils import parse_tags


class TagField(forms.CharField):

    def clean(self, value):
        value = super().clean(value)

        if "," not in value and '"' not in value and value:
            return [value]

        try:
            return parse_tags(value)
        except ValueError:
            raise forms.ValidationError(
                _("Please provide a comma-separated list of tags.")
            )

Der Code wird aus taggit/forms.py extrahiert.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen