2015-11-06 69 views
-1

的描述使用Django LogEntry(ContentType的)與GenericRelation場

我在一個Django項目,將讓所有的LogEntry在一個特定的模型,並通過具體的型號的字段進行篩選他們寫一個API。 所以我的模型看起來像這樣:

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的項目,是指HomeItem並能夠訪問它和序列化的結果groups它們進行過濾查詢視圖。所以是這樣的:

log_entry_queryset = LogEntryProxy.objects.filter(log_homeitem__groups__in=user.groups.all()).distinct() 

我的串行器看起來像這樣(使用 「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',) 

和它的作品!

的問題

那麼,什麼是你可能會問的問題!

問題是,LogEntry行爲就像創建和編輯工作!並且API會給你結果,但是當你刪除一個對象時,所有指向它的對象也將被刪除,因此api將不會給出刪除操作(加上所有的創建和編輯操作都會指向這個對象對象也將被刪除)。這都是因爲Django的GenericRelation不支持on_delete。如果我刪除GenericRelatin字段,這不會發生,但是我必須能夠在LogEntryProxy查詢集中過濾HomeItem,groups,並且不能在沒有GenericRelation的情況下完成。

我在想,如果有人能告訴我在這種情況下該怎麼做?

我應該實施自定義日誌記錄系統嗎?或者還有另一種我還沒有看到的方式!

回答

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

更新: 以上查詢將不會獲取刪除操作的logentries。 ,它可以像做:

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() 
+0

我想這需要這也太'LogEntryProxy.objects.filter(object_id__in = homeids,content_type_id = ContentType.objects.get_for_model(HomeItem).ID).distinct()'來獲得HomeItem對象不是其他模型的對象,其ID與在答案中傳遞的ID相同 – Behzad

+0

@BehzadMokhtarei哦,是的,我錯過了那個。我會編輯我的答案。 –

+0

這是令人尷尬的,但我想我們錯過了這裏的大圖,刪除的對象將不會在我們首先做的HomeItem查詢集中。所以再次刪除行動將不會顯示,所以我想這個代碼會讓我們更好'從django.db.models導入Q;來自django.contrib.admin.models的 import DELETION; ct_id = ContentType.objects.get_for_model(HomeItem).id; log_entry_queryset = LogEntryProxy.objects。過濾器(Q(object_id__in = home_ids,content_type_id = ct_id)| Q(action_flag = DELETION,content_type_id = ct_id))。distinct()' – Behzad

相關問題