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 单个选项书籍。

现有选项:

  1. Filter_horizontal - 按 __str__ 过滤,有没有办法按 tags__name 过滤?
  2. 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