Django Postgresql JsonField查询相关的字典键

时间:2017-12-01 09:59:29

标签: python django postgresql django-jsonfield postgresql-json

我使用Django Model字段的模型的一部分如下所示:

class SalesModel(models.Model):
    some_data = models.PositiveIntegerField(db_index=True)
    some_other_data = models.CharField(max_length=50)
    json_data = JSONField(blank=True, null=True)

现在,以下是JsonData字段的格式:

[{"id": val, "contribution": "some_val", }, {"id": some_val, "contribution": "some_other_val",}, {"id": other_val, "contribution": "some_another_val"}]

即格式为:

 [{'id':XX, 'contribution':XX},{'id':YY, 'contribution':YY},{'id':ZZ, 'contribution':ZZ}]

目前我可以使用ID的val过滤Django表。我现在想知道该特定ID的贡献。

例如,如果val = 1,我想过滤具有id = 1的JsonField的模型 SalesModel ,并且我想显示相关的贡献。因此,这意味着,在3个可能的字典中(根据字段构造),我只会显示一个字典(通过该字典的“ID”键过滤)。这意味着,如果第二个字典具有匹配的ID,则仅显示第二个贡献,如果第一个ID匹配则仅显示第一个贡献,并且类似地显示第三个字典。

有没有办法可以做到?

3 个答案:

答案 0 :(得分:3)

您可以通过直接给出一个密钥,值对为JSONField的字典来重新构建id: contribution has_key。通过这种方式,您可以使用KeyTransform过滤器,而json_data将起作用,因为我不确定它是否适用于一系列dicts。假设您的{1: 'xx', 3: 'yy', 9: 'zz'} 看起来像这样:

SalesModel.filter(json_data__has_key=id)\
    .annotate(contrib=KeyTransform(id, 'json_data')\
    .values('contrib')

你可以根据@vanojx1贡献:

以这种方式查询
SalesModel.filter(json_data__has_key=id)\
    .extra(select={'contrib': "json_data->{0}".format(id)})\
    .values('contrib')

或者,在postgresql中使用原始jsonb:

 import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {FormControl, Validators} from '@angular/forms';
import { Router } from '@angular/router';
import { Location } from '@angular/common';
import { Http, Response } from '@angular/http';
import { NgModel } from '@angular/forms';

import {DataSource} from '@angular/cdk/collections';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/observable/fromEvent';
import { User } from '../some';


@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
})


 export class HomeComponent implements OnInit {

    public Visits: any;

   public constructor(private location: Location, private http: Http, private router: Router){
      this.Visits = [];
       }

   public ngOnInit() {
    this.http.get('http://localhost:8080/api/visit')
    .map(result =>  ['result'])
    .subscribe(result => {
        this.Visits = result ;
        console.log('submit get click happend ' + this.Visits );
    return this.Visits;

    });

  }
      create= function () {
        this.router.navigate(['/']);

        }

      }

答案 1 :(得分:1)

这应该有效DOC

SalesModel.objects.filter(json_data__id=1).values('id', 'json_data__contribution')

答案 2 :(得分:0)

是的,我猜。如果我理解正确,您将拥有匹配的ID或ID的列表。所以如果你的身份证是2:

my_id = 2
dict1 = [{"id":1, "contribution":10},{"id":2, "contribution":20},{"id":3, "contribution":30}] 
for i in dict1:
    if i["id"] == my_id:
        print(i["contribution"])