【问题标题】:Find an object in Django using a list inside JSONField使用 JSONField 中的列表在 Django 中查找对象
【发布时间】:2021-02-18 16:04:13
【问题描述】:

我在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()

还有event_dataJSONField,其结构如下:

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

其中variant_data_list 是具有3 str 值的dict 对象的列表:

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

现在,我需要一种方法来根据提供的variant_data_list 找到唯一的Event 模型对象(其中的每个对象都应该在单个Events'variant_data_list 中找到,是否可以实现不知何故?variant_data_list 中的项目数从13

否则我正在考虑在每次写入postgres 时根据variant_data_list 生成唯一ID(但也不知道如何制作)。任何建议将不胜感激。

【问题讨论】:

    标签: django postgresql python-2.7 django-models


    【解决方案1】:

    您可能能够按照此答案 (Django JSONField filtering) 中的说明过滤 json 字段 - 以下内容未经测试:

    # 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',
        ...
    )
    

    您可以通过遍历所有可能效率较低的事件来获取对象列表:

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

    您还可以按照您的建议覆盖事件的保存方法:

    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)
    

    【讨论】:

    • 我不知道如何正确使用散列来实现它,这样就不会发生冲突。第一种方法可能不起作用,因为列表中对象的顺序可能不同,但顺序应该无关紧要。
    • 好吧,variant_data_id 字段本身不需要是唯一的,但也许您希望它...您可以更改查询以使用 @987654325 来说明列表中项目的顺序@ - 查看编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    • 2017-07-03
    • 1970-01-01
    相关资源
    最近更新 更多