THE DESCRIPTION
I'm writing an API on a Django project that will get all the LogEntry
on a specific model and filter them by the specific model's field.
So my model looks like this:
from django.contrib.admin.models import ContentType, LogEntry
from django.contrib.auth.models import Group
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.db import models
class LogEntryProxy(LogEntry):
content_object = GenericForeignKey()
class Meta:
proxy = True
class HomeItem(models.Model):
# Some Fields
groups = models.ManyToManyField(Group, related_name="home_item_group")
log_entry_relation = GenericRelation(LogEntryProxy, related_query_name='log_homeitem')
In the view I need to be able to make queries that fetch LogEntryProxy
items that refer to HomeItem
and filter them by the groups
that have access to it and serialize the results. so something like this:
log_entry_queryset = LogEntryProxy.objects.filter(log_homeitem__groups__in=user.groups.all()).distinct()
My serializer looks like this (using "djangorestframework"):
from rest_framework import serializers
class LogEntryHomeItemSerializer(serializers.ModelSerializer):
content_object = HomeItemSerializer(many=False)
object_id = serializers.IntegerField()
class Meta:
model = LogEntryProxy
fields = ('object_id', 'action_flag', 'content_object', )
And it works!
THE PROBLEM
So what's the problem you may ask!
The Problem is that LogEntry
actions like create and edit work! and the API will give you the results, but when you delete a HomeItem
object all the LogEntry
objects pointing to it will be deleted as well, thus no delete action will be given by the api (plus all the create and edit ones pointing to that object will be deleted as well). and that's all because Django's GenericRelation
doesn't support on_delete
. If I delete the GenericRelatin
field this doesn't happen but then I have to be able to filter the HomeItem
by groups
in the LogEntryProxy
queryset and it can't be done without the GenericRelation
.
I was wondering if anyone could tell me what to do in this situation?
Should I implement a custom logging system? or there's another way that I haven't seen it yet!
try:
homeids = HomeItem.objects.filter(groups__in=user.groups.all()).values_list('id',flat=True)
log_entry_queryset = LogEntryProxy.objects.filter(object_id__in=homeids,content_type_id=ContentType.objects.get_for_model(HomeItem).id).distinct()
If you query this way you don't need GenericRelation
Update: The above query will not fetch logentries of delete action. It can be done like:
from django.db.models import Q
from django.contrib.admin.models import DELETION
log_entry_queryset = LogEntryProxy.objects.filter(Q(object_id__in=home_ids,content_type_id=ContentType.objects.get_for_model(HomeItem).id) | Q(action_flag=DELETION,content_type_id=ContentType.objects.get_for_model(HomeItem).id)).distinct()