Django admin select 基于标签的 m2m 项目(项目的 m2m 字段)
Django admin select m2m items based on their tags (item's m2m field)
考虑以下模型:
class Library(models.Model):
name = models.CharField(max_length=64)
books = models.ManyToManyField(Book)
class Book(models.Model):
name = models.CharField(max_length=64)
tags = models.ManyToManyField(Tag)
class Tag(models.Model):
name = models.CharField(max_length=64)
在图书馆管理员中,我想根据标签添加书籍,同时保留 add/remove 单个选项书籍。
现有选项:
- Filter_horizontal - 按
__str__
过滤,有没有办法按 tags__name
过滤?
- Raw_id_fields - 适用于为 Book 指定的任何过滤器,但您只能 select 1 项.有没有办法允许 selection 更多项目? (table 中的复选框)
我最终使用了 Django-fsm 小部件并在 views.py
中覆盖了它的 apply_filter_val
方法。现在我可以过滤一个键 tag:tag_name
,然后只过滤 select 所有项目。我还添加了一个选项来过滤以逗号分隔的多个单词。
def apply_filter_val(self, filter_val, queryset):
if filter_val and 'tag:' in filter_val:
tag_tuple = filter_val.split(':')
_, name = tag_tuple
params = {'tags__name': name}
new_base = queryset.filter(**params)
elif filter_val and ',' in filter_val:
new_base = queryset.filter(id__in=filter_val.split(','))
elif filter_val:
q = [Q(**{f'{field}__icontains': filter_val}) for field in self.fields]
if filter_val and q:
new_base = queryset.filter(reduce(self.default_operator, q))
else:
# Return everything if no filter_val or fields are specified.
# This allows for a very straightforward async request, but will
# probably not behave as expected if no fields are specified.
new_base = queryset
if self.obj_limit:
new_base = new_base[:self.obj_limit]
return new_base
考虑以下模型:
class Library(models.Model):
name = models.CharField(max_length=64)
books = models.ManyToManyField(Book)
class Book(models.Model):
name = models.CharField(max_length=64)
tags = models.ManyToManyField(Tag)
class Tag(models.Model):
name = models.CharField(max_length=64)
在图书馆管理员中,我想根据标签添加书籍,同时保留 add/remove 单个选项书籍。
现有选项:
- Filter_horizontal - 按
__str__
过滤,有没有办法按tags__name
过滤? - Raw_id_fields - 适用于为 Book 指定的任何过滤器,但您只能 select 1 项.有没有办法允许 selection 更多项目? (table 中的复选框)
我最终使用了 Django-fsm 小部件并在 views.py
中覆盖了它的 apply_filter_val
方法。现在我可以过滤一个键 tag:tag_name
,然后只过滤 select 所有项目。我还添加了一个选项来过滤以逗号分隔的多个单词。
def apply_filter_val(self, filter_val, queryset):
if filter_val and 'tag:' in filter_val:
tag_tuple = filter_val.split(':')
_, name = tag_tuple
params = {'tags__name': name}
new_base = queryset.filter(**params)
elif filter_val and ',' in filter_val:
new_base = queryset.filter(id__in=filter_val.split(','))
elif filter_val:
q = [Q(**{f'{field}__icontains': filter_val}) for field in self.fields]
if filter_val and q:
new_base = queryset.filter(reduce(self.default_operator, q))
else:
# Return everything if no filter_val or fields are specified.
# This allows for a very straightforward async request, but will
# probably not behave as expected if no fields are specified.
new_base = queryset
if self.obj_limit:
new_base = new_base[:self.obj_limit]
return new_base