I have an event system in my app. Every time a user deletes/updates/creates and object a new event is created in the database with the info of the object and the type of event it is.
My Event model looks something like this:
class Event(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
model = models.CharField(max_length=200)
object_id = models.IntegerField()
event_type = enum.EnumField(ModelEventType)
In this model, model is the name of the object’s model, and object_id is the ID of that object.
My app also has multiple access permissions: some objects are private to the user, while others are shared among teammates. Thus, I need to restrict events to only those that correspond to a user’s access level. To fetch each user’s events, I retrieve all objects the user has access to, obtain their IDs, and then fetch the events related to those objects.
I use a method like this to fetch the objects belonging to a user:
class Event(models.Model):
....
@staticmethod
def get_events_ids(request):
object_ids = {}
Object1 = apps.get_model("myapp", "Object1")
Object2 = apps.get_model("myapp", "Object2")
Object3 = apps.get_model("myapp", "Object3")
Object4 = apps.get_model("myapp", "Object4")
Object5 = apps.get_model("myapp", "Object5")
objects1 = Object1.objects.filter(...)
objects2 = Object2.objects.filter(...)
objects3 = Object3.objects.filter(...)
objects4 = Object4.objects.filter(...)
objects5 = Object5.objects.filter(...)
objects = {
"Object1": objects1,
"Object2": objects2,
"Object3": objects3,
"Object4": objects4,
"Object5": objects5,
}
for key in objects.keys():
object_ids[key] = list(objects[key].values_list("id", flat=True))
return object_ids
I apply this approach to many more models. With this method, I get the IDs of each model and then filter events by model and ID:
event_objects = Event.get_events_ids()
events = []
# Get the events of each model
for key in event_objects.keys():
ids = event_objects[key]
events_list = qs.filter(object_id__in=ids, model=key)
events.extend(list(events_list))
ids = [obj.uuid for obj in events]
filtered_events = qs.filter(uuid__in=ids)
The problem I’m facing is that this approach is slow and inefficient due to the large number of queries involved. Is there a way to perform a bulk fetch or something similar to improve response time? Any suggestions for optimizing this process would be greatly appreciated.