Django-filter: Filtro para Django-Taggit (solicitação)

Criado em 16 ago. 2016  ·  11Comentários  ·  Fonte: carltongibson/django-filter

Indo pelas estrelas, django-taggit é tão popular quanto django-filter, e eu acredito que é a solução ideal para marcação em Django. Ele existe desde 2010, é atualizado regularmente e tem vários colaboradores regulares.

O que você acha de um filtro django-taggit?

O mais próximo que tenho disso é:

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

Mas eu não posso fazer distinção entre maiúsculas e minúsculas (um filtro para a tag 'TeSt' deve retornar resultados com a tag 'teste').

Comentários muito úteis

Exemplo de trabalho com as bibliotecas mais recentes:

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

Todos 11 comentários

Como o TaggitFilter seria diferente de um ModelMultipleChoiceFilter normal?

Além disso, tenho certeza de que poderíamos adicionar suporte lookup_expr aqui simplesmente juntando o nome do campo com a pesquisa.

Com ModelMultipleChoiceFilter o URL deve ser field_name=tag1&field_name=tag2 , mas pode haver um número significativo de tags, tornando o URL muito longo. Não é ideal para um URL que pode ser compartilhado, por exemplo.

As tags são processadas por django-taggit usando um conjunto de regras , permitindo que uma única string seja passada contendo todas as tags.

Independentemente disso, lookup_expr em ModelMultipleChoiceFilter seria definitivamente útil!

Uma olhada rápida indica que você deve ser capaz de usar TagsField do Taggit. Isso lhe daria o comportamento de análise csv.

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

A ressalva aqui é que isso usa uma pesquisa in , que não é a solução que não diferencia maiúsculas de minúsculas que você está procurando.

Estou mais ou menos na mente de não adicionar um filtro específico para Django Taggit, por melhor que seja o pacote.

Em última análise, criar filtros de nível de projeto não é tão difícil. Uma essência decente seria um longo caminho. (O Google é ótimo para eles.)

Fico feliz em olhar para uma solicitação de pull A +, se uma aparecer, mas, longe disso, fecharei isso como fora do escopo.

OK, é justo. E quanto ao suporte para lookup_expr em ModelMultipleChoiceFilter ?

@stantond Feliz em olhar para um PR. _Mostre-me o Cödz_ 😀

Eu gostaria de poder - infelizmente não sou um desenvolvedor habilidoso, mas um PM desajeitado!

+1

Exemplo de trabalho com as bibliotecas mais recentes:

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

Use o campo slug do Tag em vez do campo name para não diferenciar maiúsculas de minúsculas. Taggit reduz os slugs por padrão.

Observe que podemos expandir a solução em https://github.com/carltongibson/django-filter/issues/460#issuecomment -507218839 com um campo personalizado se desejarmos oferecer suporte ao filtro por uma única tag que contenha um ou mais espaços em branco.

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.")
            )

O código é extraído de taggit/forms.py .

Esta página foi útil?
0 / 5 - 0 avaliações