Django在查询集和正则表达式中找到重复项

时间:2015-01-22 02:53:55

标签: django django-queryset

在Django中,是否可以使用queryset和regex找到重复项?

Django select only rows with duplicate field values 在不使用正则表达式的情况下显示:

self.values('Website').annotate(count=Count('id')).order_by().filter(count__gt=1)

我有一个模特:

class company(models.Model):
   Website = models.URLField(blank=True, null=True )

我想找到带有正则表达式的副本

例如。

Company.objects.create(Website='http://example.com')
Company.objects.create(Website='http://www.example.com')

这两个都是同一个网站。我想使用正则表达式,以便返回这些公司作为重复。

我知道有像这样的过滤器使用正则表达式。我不确定如何更新它以使用正则表达式:

self.values('Website').annotate(count=Count('id')).order_by().filter(count__gt=1)

我想做类似的事情:

Website__iregex='http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'

更新 有一些混乱,所以我举一个例子。

这是我的数据库的样子

Company.objects.create(Website='http://example.com')
Company.objects.create(Website='http://www.example.com')
Company.objects.create(Website='http://example.org', Name='a')
Company.objects.create(Website='http://example.org', Name='b')

当我打电话

Company.objects.all().values('Website').annotate(count=Count('id')).order_by().filter(count__gt=1)

它返回:

  1. http://example.org(来自name = a)和http://example.org(来自name = b)
  2. 缺少example.com和www.example.com是同一个网站。

    我想使用正则表达式,以便告诉django example.com和www.example.com是相同的网站。

    我想修改:

    Company.objects.all().values('Website').annotate(count=Count('id')).order_by().filter(count__gt=1)
    

    以便它返回重复项:

    1. http://example.org(来自姓名= a)和http://example.org(来自姓名= b)

    2. example.com www.example.com

2 个答案:

答案 0 :(得分:1)

使用__icontains

Company.objects.filter(Website__icontains='example.com')

将产生:

`ILIKE %'example.com'%. 

如果存在于公司表中,它将返回以下记录:

 http://example.com, http://www.example.com

答案 1 :(得分:0)

我在某个项目上有类似的DB结构 - 我存储了一些实体的URL。为了找到重复项,我还存储了网址的“域名”。

因此,关于您的示例,数据库结构将是:

id |           url          | domain
-----------------------------------------
1  | http://www.example.com | example.com
2  | http://example.com     | example.com

然后很容易找到重复项或找到与特定域相关的网址/实体。

你可能认为使用这种方法对于检测重复是一种过度的做法。

但是你的方法有两大缺点:

1)无法编写与域变体相匹配的正确正则表达式

匹配“www.example.com”和“example.com”很容易。 “example.co.uk”和“www.example.co.uk”或者“www.старт.рф”和“старт.рф”怎么样?这些都是有效的域名。

2)从长远来看,你正在拍摄你的腿 - 在不断增长的数据库表格上编写复杂的正则表格杀死你的表现。

P.S。 - 我使用“tldextract”lib获取网址域。