Nikita Vlasenko
Nikita Vlasenko

Reputation: 4352

Find an object in Django using a list inside JSONField

I have such a model in Django:

class Event(models.Model):                                                                                                 
    EVENT_TYPE_CHOICES = [(e, e.value) for e in EVENT_TYPE]                                                                
    event_type = models.TextField(choices=EVENT_TYPE_CHOICES)                                                              
                                                                                                                           
    date_of_event = models.DateTimeField(default=timezone.now, db_index=True)                                              
    event_data = JSONField()

And there is the event_data JSONField there which has the following structure:

    'project_id': project_id,                                                                                       
    'family_id': family_id,                                                                                         
    'variant_data': variant_data_list,                                                                              
    'username': user.username,                                                                                      
    'email': user.email, 

Where variant_data_list is a list of such dict objects with 3 str values:

{'xpos': xpos, 'ref': ref, 'alt': alt}

Now, I need a way to find unique Event model object based on the supplied variant_data_list (each object inside of it should be found within a single Events' variant_data_list, is it possible to achieve somehow? The number of items in variant_data_list is from 1 to 3.

Otherwise I am thinking of generating unique ids based on the variant_data_list each time it is written to postgres (but not sure how to make it either). Any suggestions would be greatly appreciated.

Upvotes: 0

Views: 70

Answers (1)

Daniel
Daniel

Reputation: 3527

You may be able to filter on json fields as illustrated in this answer (Django JSONField filtering) - the following is untested:

# filter for events with a specific variant_data list:
Event.objects.filter(event_data__variant_data=[<the list>])

# filter for events with specific items in the variant data list:
Event.objects.filter(
    event_data__variant_data__contains='item1', 
    event_data__variant_data__contains='item2',
    ...
)

You can get a list of objects by looping over all your events which is likely less efficient:

events = [
    event for event in Event.objects.all() if event.event_data['variant_data'] == [<the list>]
]

You can also override your save method on events to as you suggested:

class Event(...):

    variant_data_id = models.CharField(...)
  
    ...
   
    def save(self, *args, **kwargs):

        self.variant_data_id = some_hash_method(self.event_data['variant_list']

        super(Event, self).save(*args, **kwargs)

Upvotes: 1

Related Questions