I am receiving an object from the frontend as a parameter alongside with other parameters. How can I store that object into my model?
I've tried JSONfield but not sure if its the best way to do it. This will be a tracking service like Mixpanel
this is roughly the object looks like in the front end:
myObj = {
context: ["Home Page"]
dropDown: "navigated to main screen"
side: "creator-side"
withSelection: false
}
and I want to have it in 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 }
I want to be able to filter the events based on the properties in the object on admin panel.
If you're using PostgreSQL, you can take advantage of the Django field type JSONField
to make a model field that stores a structured JSON object. Then you can add a custom filter to query on JSON in the Django admin.
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()
Custom Filter
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
So you can use the custom filter like this (e.g. for side
property) in your admin.py.
class SideFilter(JSONFieldFilter):
title = 'Side'
parameter_name = 'side'
json_field_name = 'detail'
json_field_property_name = 'side'
class TrackedEventsAdmin(admin.ModelAdmin):
list_filter = [SideFilter]