Как оптимизировать метод с несколькими вызовами запроса?
У меня есть система событий в моем приложении. Каждый раз, когда пользователь удаляет/обновляет/создает объект, в базе данных создается новое событие с информацией об объекте и типе события. Моя модель событий выглядит примерно так:
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)
В этой модели model - это имя модели объекта, а object_id - идентификатор этого объекта.
Мое приложение также имеет несколько разрешений доступа: некоторые объекты являются частными для пользователя, а другие - общими для членов команды. Таким образом, мне нужно ограничить события только теми, которые соответствуют уровню доступа пользователя. Чтобы получить события каждого пользователя, я получаю все объекты, к которым у пользователя есть доступ, получаю их идентификаторы, а затем получаю события, связанные с этими объектами.
Я использую такой метод для получения объектов, принадлежащих пользователю:
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
Я применяю этот подход к гораздо большему числу моделей. С помощью этого метода я получаю идентификаторы каждой модели, а затем фильтрую события по модели и идентификатору:
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)
Проблема, с которой я столкнулся, заключается в том, что этот подход медленный и неэффективный из-за большого количества запросов. Есть ли способ выполнить массовую выборку или что-то подобное, чтобы улучшить время отклика? Любые предложения по оптимизации этого процесса будут высоко оценены.
если вам нужен только pk, используйте filter и values_list.
def aa():
a = model.objects.filter(a={})
if user.permission == 1:
a = a.objects.filter({permission query)
if user.permiision == 2:
...
return a.values_list('pk', flat=True)