الذهاب من خلال النجوم ، django-taggit مشهور مثل django-filter ، وأعتقد أنه الحل المناسب لوضع العلامات في Django. لقد كان موجودًا منذ عام 2010 ، ويتم تحديثه بانتظام ، ولديه العديد من المساهمين المنتظمين.
ما رأيك في مرشح django-taggit؟
أقرب ما لدي إلى هذا هو:
tags = django_filters.ModelMultipleChoiceFilter(
name='tags__name',
to_field_name='name',
conjoined=True,
distinct=True,
queryset=Tag.objects.all(),
)
لكن لا يمكنني جعلها غير حساسة لحالة الأحرف (يجب أن يعرض مرشح العلامة "TeSt" النتائج بعلامة "اختبار").
كيف يمكن أن يختلف TaggitFilter
عن ModelMultipleChoiceFilter
العادي؟
أيضًا ، أنا متأكد من أنه يمكننا إضافة دعم lookup_expr
هنا ببساطة عن طريق الانضمام إلى اسم الحقل مع البحث.
باستخدام ModelMultipleChoiceFilter
، يجب أن يكون عنوان URL هو field_name=tag1&field_name=tag2
، ولكن قد يكون هناك عدد كبير من العلامات ، مما يجعل عنوان URL طويلًا جدًا. ليست مثالية لعنوان URL يمكن مشاركته ، على سبيل المثال.
تتم معالجة العلامات بواسطة django-taggit باستخدام مجموعة من القواعد ، مما يسمح بتمرير سلسلة واحدة تحتوي على جميع العلامات.
بغض النظر ، سيكون lookup_expr
في ModelMultipleChoiceFilter
مفيدًا بالتأكيد!
نظرة سريعة تشير إلى أنه يجب أن تكون قادرًا على استخدام TagsField
Taggit. هذا من شأنه أن يمنحك سلوك تحليل 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
التحذير هنا هو أن هذا يستخدم in
lookup ، وهو ليس الحل الذي لا يتأثر بحالة الأحرف الذي تبحث عنه.
أنا أكثر أو أقل من العقل في عدم إضافة مرشح معين لـ Django Taggit ، حزمة رائعة على الرغم من أنها قد تكون كذلك.
في النهاية ، إنشاء عوامل تصفية على مستوى المشروع ليس بالأمر الصعب. إن الجوهر اللائق سيقطع شوطا طويلا. (يعد Google مكانًا رائعًا لهؤلاء.)
يسعدني إلقاء نظرة على طلب سحب A + إذا ظهر أحد ، ولكن أقل من ذلك سأغلق هذا على أنه خارج النطاق.
حسنًا ، عادل بما يكفي. ماذا عن دعم lookup_expr
في ModelMultipleChoiceFilter
؟
stantond سعيد
أتمنى لو أستطيع - لسوء الحظ أنا لست مطورًا ماهرًا ، لكنني أتخبط!
+1
مثال للعمل مع أحدث المكتبات:
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
استخدم الحقل slug
بالعلامة بدلاً من الحقل name
لتكون حساسًا لحالة الأحرف. Taggit الحالات المنخفضة الرخويات بشكل افتراضي.
لاحظ أننا قد نوسع الحل في https://github.com/carltongibson/django-filter/issues/460#issuecomment -507218839 بحقل مخصص إذا أردنا دعم التصفية بعلامة واحدة تحتوي على مسافة بيضاء واحدة أو أكثر.
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.")
)
يتم استخراج الكود من taggit/forms.py
.
التعليق الأكثر فائدة
مثال للعمل مع أحدث المكتبات: