将Django LogEntry(ContentType)与GenericRelation字段一起使用

时间:2015-11-06 11:00:20

标签: django django-queryset django-contenttypes

描述

我正在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

我想知道是否有人能告诉我在这种情况下该怎么做?

我应该实施自定义日志记录系统吗?或者还有另一种我尚未见过的方式!

1 个答案:

答案 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()