如何根据Django中的某些字段查找重复记录

时间:2019-01-18 07:45:59

标签: python django

我需要在queryset中创建一个新字段,以标记记录是否重复。我认为2个字段的串联值是一个标识符。如果在查询集中(已连接的字段)多次看到它们,那么该记录将被视为重复记录。

首先,在我的查询集上,我从现有的2个字段中创建另一个字段,即案件编号和聆讯日期。其输出字段名称为dupe_id

    qs = file.objects.annotate(
            dupe_id=Concat(
                        F('case_no')
                        , F('hearing_date')
                        , output_field=CharField()
            )
        )

然后我测试这个dupe_id字段的计数。如果计数大于1,则视为重复

    dupes = qs.values('dupe_id').annotate(dupe_count=Count('dupe_id')).filter(dupe_count__gt=1)

这时,我现在有了另一个查询集,其中包含原始查询集中的重复值。这是从查询类型为dupe的对象看到的记录。它还说明了找到该值的实例数

<QuerySet [{'dupe_id': 'Test Case No.2018-12-26', 'dupe_count': 3}, {'dupe_id': '123452018-12-26', 'dupe_count': 2}]>

现在这是我有点困难的地方。我在想的是,我将在主查询集上做一个注释,并且将使用dupes查询集来帮助识别需要标记为重复的记录。

我尝试过:

    qs = qs.annotate(
            dupe_id2 = Value(('duplicate' if dupes.filter(dupe_id__exact=Concat(F('case_no'), F('hearing_date')))[0] else '--'), output_field=CharField())
        )

这只是一个简单的测试,该测试表明如果在dupes查询集中看到并置的值,则该字段将被标记为重复项,否则将被标记为“-”。

但是它似乎没有按预期工作。即使我有1条不应该标记为重复的记录,所有记录也都被标记为重复。

我也使用条件表达式进行了检查,但无法使用我创建的dupes查询集。

如果存在将查询集中的记录标记为重复的更健壮的方法,请告诉我。

2 个答案:

答案 0 :(得分:1)

处理重复项的方法之一是使用以下算法:
在SQL中使用GroupBy>查找重复项>遍历重复项

from django.db.models import Max, Count

# Getting duplicate files based on case_no and hearing_date
files = File.objects.values('case_no', 'hearing_date') \
    .annotate(records=Count('case_no')) \
    .filter(records__gt=1)

# Check the generated group by query
print files.query

# Then do operations on duplicates
for file in files:
    File.objects.filter(
        case_no=file['case_no'],
        hearing_date=file['hearing_date']
    )[1:].update(duplicate=True)

答案 1 :(得分:0)

事实证明,不可能对查询集的注释功能执行条件操作。

我所做的是重写get_context_data函数,然后获取重复的键。返回的对象是一个查询集,因此我获取了所有ID,然后将它们放在列表中,然后将其存储到可以在模板视图中使用的上下文中。

这是我的get_context_data函数的外观,如果可以进一步改进,请告诉我。

var cars = ["BMW", "Volvo", "Saab", "Ford", "Fiat", "Audi"];
var text = "";
var i;
for (i = 0; i < cars.length; i++) {
  text += cars[i] + "<br>";
} //I want to get car[i] (car[0])

现在在模板视图的queryset的for循环上,我刚刚创建了另一列,该列用于检查queryset中的id在重复项列表中是否可见,那么记录将具有特殊的重复项标签或单元格将突出显示为用户可见的内容。

def get_context_data(self, **kwargs):
    ctx = super(fileList, self).get_context_data(**kwargs)

    qs = file.objects.annotate(
            dupe_id=Concat(
                        F('case_no')
                        , F('hearing_date')
                        , output_field=CharField()
            )
        )

    dupes = qs.values('dupe_id').annotate(dupe_count=Count('dupe_id')).filter(dupe_count__gt=1)

    dupe_keys = []
    for dupe in dupes:
        dupe_keys.append(dupe['dupe_id'])

    ctx['dupe_keys'] = dupe_keys

    return ctx