按 strip_tags(html 字符串)排序查询集

order queryset by strip_tags(html string)

在我的 Django 应用程序中,我必须按字符串属性对查询集进行排序。那是很容易的事情。但是这个字符串属性有HTML个标签,我需要把它去掉以便排序。

class Publication(models.Model):
    authors = models.CharField()

我知道 queryset.order_by() 方法,但据我所知,我不能使用任何方法去除那里的 html。

我想出了一个 "almost solution"。

>>> from django.utils.html import strip_tags
>>> sorted(Publication.objects.all(), key=strip_tags('authors'))
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/var/www/cms/venv2.7.5/lib/python2.7/site-packages/django/utils/functional.py", line 203, in wrapper
    return func(*args, **kwargs)
  File "/var/www/cms/venv2.7.5/lib/python2.7/site-packages/django/utils/html.py", line 156, in strip_tags
    if not ('<' in value or '>' in value):
TypeError: argument of type 'operator.attrgetter' is not iterable

如何对这个查询集进行排序?我的方法是否朝着正确的方向发展?有效率吗?这些查询集目前长达 +-1500 个元素。

提前致谢。

.sogeking

试试这个

sorted(Publication.objects.all(), key=lambda x: x[strip_tags('authors')])

或使用operator.itemgetter

import operator
key=operator.itemgetter('authors')

Publication.objects.all().order_by(strip_tags('authors')) #ascending
Publication.objects.all().order_by('-'+strip_tags('authors')) #descending

这不会像您那样工作。 strip_tag 操作需要在数据库级别进行,而不是在 Python.

我认为最有效的解决方案是向您的模型添加一个字段——比如 authors_stripped——以存储与 authors 字段相同的内容,但从标签中删除。然后您可以按该字段订购。 确保 authors_stripped 匹配 authors 的一种简单方法是重写模型的 save 方法:

from django.utils.html import strip_tags


class Publication(models.Model):
    authors = models.CharField()
    authors_stripped = models.CharField(editable=False)

    def __save__(self,*args, **kwargs):
        if self.authors:
            self.authors_stripped = strip_tags(self.authors)
        super(Publication, self).save(*args, **kwargs)

您可以使用找到的解决方案 here 仅在 authors 的值更改时计算 authors_stripped 值。

当且仅当您从数据库中检索所有出版物时,@itzmeontv 提出的解决方案才有效,这将被证明是大数据集的效率问题。