【问题标题】:How to store an object in a django model?如何将对象存储在 django 模型中?
【发布时间】:2019-10-22 20:42:23
【问题描述】:

我从前端接收一个对象作为参数以及其他参数。如何将该对象存储到我的模型中?

我已经尝试过 JSONfield,但不确定它是否是最好的方法。这将是一个类似于 Mixpanel 的跟踪服务

这大致是对象在前端的样子:

myObj = {
context: ["Home Page"]
dropDown: "navigated to main screen"
side: "creator-side"
withSelection: false
}

我想在 Django 中使用它:

@reversion.register()
class TrackedEvents(models.Model):
    ...
    event_name = models.TextField(max_length=250, null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    myObj = { what to add here }

我希望能够根据管理面板上对象中的属性过滤事件。

【问题讨论】:

  • 您使用的是什么 DBMS?
  • @mrzrm postgreSQL

标签: django django-models django-database


【解决方案1】:

如果您使用的是 PostgreSQL,则可以利用 Django field type JSONField 创建一个模型字段来存储 结构化 JSON 对象。然后您可以添加自定义过滤器以在 Django 管理中查询 JSON

admin.py

from django.contrib.postgres.fields import JSONField

class TrackedEvents(models.Model):
    event_name = models.TextField(max_length=250, null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    detail = JSONField()

自定义过滤器

from django.contrib.admin import SimpleListFilter

class JSONFieldFilter(SimpleListFilter):
    def __init__(self, *args, **kwargs):
        super(JSONFieldFilter, self).__init__(*args, **kwargs)
        assert hasattr(self, 'title'), (
            'Class {} missing "title" attribute'.format(self.__class__.__name__)
        )
        assert hasattr(self, 'parameter_name'), (
            'Class {} missing "parameter_name" attribute'.format(self.__class__.__name__)
        )
        assert hasattr(self, 'json_field_name'), (
            'Class {} missing "json_field_name" attribute'.format(self.__class__.__name__)
        )
        assert hasattr(self, 'json_field_property_name'), (
            'Class {} missing "json_field_property_name" attribute'.format(self.__class__.__name__)
        )

    def lookups(self, request, model_admin):
        values_list = map(
            lambda data: data[self.json_field_property_name],
            model_admin.model.objects.values_list(self.json_field_name, flat=True)
        )
        return [(v, v) for v in set(values_list)]

    def queryset(self, request, queryset):
        if self.value():
            key = "{}__{}".format(self.json_field_name, self.json_field_property_name)
            return queryset.filter(**{key: self.value()})
        return queryset

因此,您可以在 admin.py 中使用这样的自定义过滤器(例如,side 属性)。

class SideFilter(JSONFieldFilter):
    title = 'Side'
    parameter_name = 'side'
    json_field_name = 'detail'
    json_field_property_name = 'side'


 class TrackedEventsAdmin(admin.ModelAdmin):
    list_filter = [SideFilter]

【讨论】:

  • 还有一个问题,我应该将此过滤器保留在 admin.py 中还是我定义模型的位置?
  • @NaimMustafa 我建议您将SideFilterTrackedEventsAdmin 存储在您的应用程序的admin.py 中,但将JSONFieldFilter 保留在您存储实用程序的更通用的地方;因为其他应用可能会使用它。
猜你喜欢
  • 2022-10-14
  • 2021-09-27
  • 1970-01-01
  • 2015-07-07
  • 2018-08-12
  • 1970-01-01
  • 1970-01-01
  • 2019-08-09
  • 1970-01-01
相关资源
最近更新 更多