【问题标题】:django - Joining LogEntry to actual modelsdjango - 将 LogEntry 加入实际模型
【发布时间】:2012-01-26 08:40:07
【问题描述】:

所以我使用管理员 LogEntry 对象/表在我的应用程序中记录事件。我有一个视图,我想在其中显示每个 LogEntry。
如果我可以将 LogEntry 与它们所代表的实际对象一起加入,那就太好了(这样我就可以在日志条目中显示对象的属性) 理论上这应该很容易,因为我们有来自 LogEntry 的模型类型和 id,但我不知道如何使用查询集加入它们。

我认为我可以获取不同对象的所有 id 并为每个对象类型制作另一个字典,然后以某种方式加入它们(也许将列表压缩在一起?)但这看起来很愚蠢,而且不是很 djano-ish/pythonic。

有人有更好的建议吗?

** 编辑 ** 只是想澄清我不想使用管理员,而是滚动自定义视图和模板。

【问题讨论】:

    标签: django join django-models django-templates django-queryset


    【解决方案1】:

    最近的 Django 版本需要为 LogEntry 创建代理:

    from django.contrib import admin
    from django.contrib.admin.models import LogEntry
    from django.contrib.contenttypes.generic import  GenericTabularInline
    
    class LogEntryProxy(LogEntry):
        content_object = GenericForeignKey('content_type', 'object_id')
        class Meta:
            proxy = True
    
    class LogInline(GenericTabularInline):
        model = LogEntry
        extra = 0
    
    class ItemAdmin(admin.ModelAdmin):
        inlines = [LogInline,]
    
    admin.site.register(models.Item, ItemAdmin)
    

    【讨论】:

      【解决方案2】:

      据我所知,Django 使用contenttypes framework 在管理员中执行登录。因此,您应该在模型中创建通用关系,然后在管理员中使用 GenericTabularInline 和 GenericStackedInline 显示内联。请参考文章。

      from django.contrib import admin
      from django.contrib.admin.models import LogEntry
      from django.contrib.contenttypes.generic import  GenericTabularInline
      from django import forms
      from some_app import models
      from some_app.models import Item
      
      class LogForm(forms.ModelForm):
          class Meta:
              model = LogEntry
      
      class LogInline(GenericTabularInline):
          ct_field = 'content_type'
          ct_fk_field = 'object_id'
          model = LogEntry
          extra = 0
      
      class ItemForm(forms.ModelForm):
          class Meta:
              model = Item
      
      class ItemAdmin(admin.ModelAdmin):
          form = ItemForm
          inlines = [LogInline,]
      
      
      admin.site.register(models.Item, ItemAdmin)
      

      然后你添加到项目:

      class Item(models.Model):
          name = models.CharField(max_length=100)
          logs =  generic.GenericRelation(LogEntry)
      

      此更改不会在您的数据库中创建任何内容,因此无需同步

      【讨论】:

      • 酷。我以前从未使用过泛型关系。那么在我的情况下,您是否建议在我的模型中创建与 logEntry 对象的通用关系?
      • 啊感谢代码示例。让事情变得更加清晰。几件事。第一:我不想使用管理员。我想推出自己的视图和模板。第二:这种方式给了我所有项目的列表,然后在查看特定项目时,我会看到所有日志。我需要它反过来。我需要一个日志条目列表以及沿途每个项目的详细信息。这是相关的,因为我执行的查询基于 LogEntries,而不是项目。谢谢!
      • 对不起,我好像忘记了你在问什么,并回答了一些其他问题。 LogEntry 有两个字段“content_type”,它连接到 ContentType 对象,它有方法 get_object_for_this_type(*kwargs),你应该调用这个方法传递 id = log_entry.object_id。这会给你你的对象。这是 GenericForeignKey 所做的,但 LogEntry 没有,所以你必须自己实现它或设置你自己的日志记录(这并不难)。
      • 感谢您的回复,并对我的延误表示歉意。我看到了那个函数,但它似乎有点贵,因为我们必须为我们返回的每个对象进行单独的数据库调用。我想我要去实现我自己的日志记录了....(或者找一个比我聪明的人已经完成了它并成功了)。
      猜你喜欢
      • 1970-01-01
      • 2011-09-19
      • 2011-03-08
      • 1970-01-01
      • 2010-12-05
      • 1970-01-01
      • 2014-08-19
      • 2011-08-04
      • 2018-10-31
      相关资源
      最近更新 更多