【问题标题】:Django admin select m2m items based on their tags (item's m2m field)Django 管理员根据标签选择 m2m 项目(项目的 m2m 字段)
【发布时间】:2019-09-18 03:41:17
【问题描述】:
考虑以下模型:
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)
在图书馆管理中,我想根据图书的标签添加图书,同时保留添加/删除单本图书的选项。
现有选项:
-
Filter_horizontal - 按
__str__ 过滤,有没有办法按tags__name 过滤?
-
Raw_id_fields - 适用于为 Book 指定的任何过滤器,但您只能选择 1 个项目。有没有办法允许选择更多项目? (表格中的复选框)
【问题讨论】:
标签:
django
django-admin
filtering
admin
m2m
【解决方案1】:
我最终使用了Django-fsm 小部件并在views.py 中覆盖了它的apply_filter_val 方法。现在我可以过滤一个键tag:tag_name,然后选择所有项目。我还添加了一个选项来过滤以逗号分隔的多个单词。
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