2014-12-08 2 views
1

나는 아티스트와 그림으로 된 데이터베이스를 가지고 있으며 아티스트 이름과 그림 제목을 기반으로 쿼리하고 싶다. 제목은 json 파일에 있습니다 (아티스트 이름은 아약스에서 나옵니다). 그래서 루프를 시도했습니다. 내가 필요 같은여러 개의 필터가있는 장고 데이터베이스 쿼리는 어떻게 작성합니까?

def rest(request): 

    data = json.loads(request.body) 
    artistname = data['artiste'] 
    with open('/static/top_paintings.json', 'r') as fb: 
     top_paintings_dict = json.load(fb) 

    response_data = [] 

    for painting in top_paintings_dict[artist_name]: 
     filterargs = {'artist__contains': artistname, 'title__contains': painting} 
     response_data.append(serializers.serialize('json', Art.objects.filter(**filterargs))) 

    return HttpResponse(json.dumps(response_data), content_type="application/json") 

그것은 누군가를 위해 좋은하지 않습니다 그냥 못생긴 더블 직렬화 된 JSON 데이터를 개체의 목록을 반환하지 않습니다.

["[{\"fields\": {\"artist\": \"Leonardo da Vinci\", \"link\": \"https://trove2.storage.googleapis.com/leonardo-da-vinci/the-madonna-of-the-carnation.jpg\", \"title\": \"The Madonna of the Carnation\"}, \"model\": \"serve.art\", \"pk\": 63091}]", 

이 처리기는 내가 아티스트에 대해 가지고있는 모든 그림을 처리하고 반환합니다.

def rest(request): 

    data = json.loads(request.body) 
    artistname = data['artiste'] 
    response_data = serializers.serialize("json", Art.objects.filter(artist__contains=artistname)) 
    return HttpResponse(json.dumps(response_data), content_type="application/json") 

아티스트뿐 아니라 제목별로 내 검색어를 필터링하면됩니다.

+0

파이썬의 직렬화 목록을 작성한 다음 해당 목록을 직렬화합니다. json이 직렬화 된 객체 목록 또는 객체 목록 중 하나가되도록 하시겠습니까? –

+0

하나의 개체 목록이 필요합니다. 나는 Art.objects.filter()를 사용하여 하나의 아티스트 이름과 그림 제목 목록을 쿼리 할 수는 없지만 그것이 필요한 것입니다. 한 예술가, 여러 그림. –

답변

2

귀하의 문제는 데이터를 두 번 연속으로 serialize하는 것입니다. 한 번만 serializers.serialize을 입력하고 json.dumps을 입력하면됩니다.

응용 프로그램의 세부 사항을 모르지만 django에서 필터를 연결할 수 있습니다. 그래서 나는 두 번째 접근 방식으로 갈 것 그냥

response_data = serializers.serialize("json", Art.objects.filter(artist__contains=artistname).filter(title__in=paintings)) 

확인 queryset documentation와 라인

response_data = serializers.serialize("json", Art.objects.filter(artist__contains=artistname)) 

를 교체합니다.

+0

제목이 하나뿐 아니라 여러 개의 제목이 있습니다. 코드는 하나의 객체만을 반환합니다. 나는 이미 직렬화 된 객체의 목록을 만들려고 시도했지만 유용하지 않다. –

+0

in 필터를 사용해보십시오. 나는 그 대답을 편집했다. – Nebril

+0

좋은 물건, 그 속임수를했다. –

2

그림 제목에 __contains 검색이 작업을 수행하는 가장 효율적인 방법은 함께 모든 가능한 그림 이름을 Q objectsor에를 사용하는 것입니다 : 그것은 당신에게 그림의 검색어 세트를 얻을 수 있습니다

from operator import or_ 

def rest(request): 

    data = json.loads(request.body) 
    artistname = data['artiste'] 
    with open('/static/top_paintings.json', 'r') as fb: 
     top_paintings_dict = json.load(fb) 

    title_filters = reduce(or_, (Q(title__contains=painting) for painting in top_paintings_dict[artist_name])) 
    paintings = Art.objects.filter(title_filters, artist__contains=artist_name) 

. 귀하의 이중 직렬화가 올바르지 않다고 생각하지만 단일 아티스트 이름의 케이스에서 귀하가 만족 스럽습니다.

는 여기 reduce 호출은 여러에게 Q 객체를 함께 보내고 |의 결과를 구축하는 방법입니다 - operator.or_|에 대한 기능 핸들, 그리고 나서 각 그림의 이름에 대한 Q 객체를 생성하는 발전기 표현을 사용하고 있습니다 .

+0

더 이상 이중 직렬화가 아닙니다. –

+0

귀하의 답변에는 배워야하는 몇 가지 고급 방법이 포함되어 있습니다. –

+1

'Q' 오브젝트는 학습 가치가 있습니다. 'reduce'와'연산자를 건너 뛸 수 있습니다.or_' 만약 당신이 그들에 대해 확실하지 않고'title_filters = Q (title__contains = top_paintings_dict [artist_name] [0]); top_paintings_dict에서 그림을 그리기 [artist_name] [1 :] : title_filters = title_filters | Q (title__contains = 그림)' –

관련 문제