Home > Software design >  Django: Filter matching objects using 2 fields
Django: Filter matching objects using 2 fields

Time:12-17

I have the following classes:


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)

Each event has one or several IOCs associated with it, which are stored in the IOCInfo table.

This is how my IOCInfo table looks like after creating some events:

id value event_id ioc_type_id
1 some-value1 eventid1 4
2 some-value2 eventid1 8
3 some-value3 eventid1 8
4 some-value4 eventid1 1
5 some-value3 eventid2 8
6 some-value1 eventid2 1
7 some-value2 eventid3 8
8 some-value3 eventid4 8

What I want to do is to take an event, compare its IOCInfo with those of other events and get back those events that match.

This is what I have done so far and it works, but I fear that as the database grows and the app has more users this query will end up being a bottleneck


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)

If I pass the eventid2 to The above function, it will return eventid1 and eventid4 as expected.

Any suggestions to improve this function using any django method would be appreciated.

CodePudding user response:

If I understand correctly:

  1. Filter iocs that correspond to given event:

    iocs = IOCInfo.objects.filter(event=event)
    
  2. Get events that has the same iocs (except the given one)

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

That will result in a single pretty efficent query.

CodePudding user response:

Let's see if I understand...

def search_matches(event):
    return Event.objects.filter(iocs__in=event.iocs.all()).exclude(pk=event.id)
  • Related