python Django:使用2个字段过滤匹配对象

b4lqfgs4  于 2022-12-17  发布在  Python
关注(0)|答案(2)|浏览(139)

我有以下课程:

class Event(Model):
    ...

class IOCType(Model):
    name = CharField(max_length=50)

class IOCInfo(Model):
    event = ForeignKey(Event, on_delete=CASCADE, related_name="iocs"
    ioc_type = ForeignKey(IOCType, on_delete=CASCADE)
    value = CharField(max_lenght=50)

每个事件都有一个或多个与其关联的IOC,这些IOC存储在IOCInfo表中。
创建一些事件后,IOCInfo表的外观如下所示:
| 身份证|价值|事件标识|ioc类型标识|
| - ------|- ------|- ------|- ------|
| 1个|某值1|事件1|四个|
| 第二章|某值2|事件1|八个|
| 三个|某值3|事件1|八个|
| 四个|某值4|事件1| 1个|
| 五个|某值3|事件2|八个|
| 六个|某值1|事件2| 1个|
| 七|某值2|事件3|八个|
| 八个|某值3|事件4|八个|
我想要做的是获取一个事件,将其IOCInfo与其他事件的IOCInfo进行比较,然后返回匹配的事件。
这是我目前所做的工作,并且效果不错,但我担心随着数据库的增长和应用程序用户的增加,这种查询最终会成为瓶颈

def search_matches(event):
    matches = Event.objects.none() 
    for ioc in event.iocs.all():
        matches |= Event.objects.filter(
            iocs__ioc_type=ioc.ioc_type, iocs__value=ioc.value
        )
    return matches.exclude(event=event.id)

如果我将eventtid 2传递给上述函数,它将返回预期的eventtid 1和eventtid 4。
任何使用django方法改进此功能的建议都将受到欢迎。

e4eetjau

e4eetjau1#

如果我理解正确的话:
1.筛选与给定事件对应的IOC:

iocs = IOCInfo.objects.filter(event=event)

1.获取具有相同IOC的事件(给定的除外)

events = Event.objects.filter(iocs__in=iocs).exclude(pk=event.pk)

这将产生一个非常有效的查询。

jqjz2hbq

jqjz2hbq2#

让我们看看我是否理解...

def search_matches(event):
    get_values = lambda data, key: [x[key] for x in data]

    ioc_types = event.iocs.all().values('ioc_type')
    ioc_values = event.iocs.all().values('value')

    return Event.objects.filter(
        iocs__ioc_type__in=get_values(ioc_types),
        iocs__value__in=get_values(ioc_values)
    ).exclude(pk=event.id)

相关问题