描述
我正在Django项目上编写一个API,它将获取特定模型上的所有LogEntry
并按特定模型的字段过滤它们。
所以我的模型看起来像这样:
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')
在视图中,我需要能够进行查询,以获取引用LogEntryProxy
的{{1}}项,并通过有权访问它的HomeItem
过滤它们并序列化结果。所以像这样:
groups
我的序列化程序看起来像这样(使用" djangorestframework"):
log_entry_queryset = LogEntryProxy.objects.filter(log_homeitem__groups__in=user.groups.all()).distinct()
它有效!
问题
那么你可能会问的问题是什么!
问题在于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', )
动作,如创建和编辑工作! API将为您提供结果,但是当您删除LogEntry
对象时,所有指向它的HomeItem
对象也将被删除,因此api不会给出删除操作(加上所有指向该对象的创建和编辑也将被删除)。这一切都是因为Django的LogEntry
不支持GenericRelation
。如果我删除了on_delete
字段,但这不会发生,但我必须能够在GenericRelatin
查询集中按HomeItem
过滤groups
,它可以&# 39;没有LogEntryProxy
。
我想知道是否有人能告诉我在这种情况下该怎么做?
我应该实施自定义日志记录系统吗?或者还有另一种我尚未见过的方式!
答案 0 :(得分:0)
尝试:
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()
如果您以这种方式查询,则不需要GenericRelation
更新: 上面的查询不会获取删除操作的异常。 可以这样做:
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()