Como faço para converter um Django QuerySet em uma lista de dicts?


122

Como posso converter um Django QuerySet em uma lista de dicts? Não encontrei uma resposta para isso, então estou me perguntando se estou perdendo algum tipo de função auxiliar comum que todos usam.

Respostas:


176

Use o .values()método:

>>> Blog.objects.values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}],
>>> Blog.objects.values('id', 'name')
[{'id': 1, 'name': 'Beatles Blog'}]

Nota: o resultado é um QuerySetque geralmente se comporta como uma lista, mas não é realmente uma instância de list. Use list(Blog.objects.values(…))se você realmente precisar de uma instância de list.


7
sim, você especifica quais campos deseja values()retornar, passando-os como argumentos. Também tenha cuidado, embora pareça que os valores retornam uma lista de dados, na verdade, é um <class 'django.db.models.query.ValuesQuerySet'>e não uma lista.
dm03514

10
na verdade, isso não retorna uma lista
astreltsov

Além disso, você não pode obter os resultados dos métodos de instância do seu objeto com values(), não sei se existe um bom método para fazer o mesmo, values()mas também com a chamada dos métodos de instância ?!
Asara

34

O .values()método retornará um resultado do tipo ValuesQuerySetque normalmente é o que você precisa na maioria dos casos.

Mas, se desejar, você pode transformar ValuesQuerySetem uma lista Python nativa usando a compreensão de lista Python, conforme ilustrado no exemplo abaixo.

result = Blog.objects.values()             # return ValuesQuerySet object
list_result = [entry for entry in result]  # converts ValuesQuerySet into Python list
return list_result

Acho que o acima ajuda se você estiver escrevendo testes de unidade e precisar afirmar que o valor de retorno esperado de uma função corresponde ao valor de retorno real, caso em que ambos expected_resulte actual_resultdevem ser do mesmo tipo (por exemplo, dicionário).

actual_result = some_function()
expected_result = {
    # dictionary content here ...
}
assert expected_result == actual_result

17
Ou você pode simplificar a conversão para lista com estelist(result)
Adiyat Mubarak

12

Se você precisar de tipos de dados nativos por algum motivo (por exemplo, serialização JSON), esta é minha maneira rápida e suja de fazer isso:

data = [{'id': blog.pk, 'name': blog.name} for blog in blogs]

Como você pode ver, construir o dict dentro da lista não é realmente SECO, então se alguém conhece uma maneira melhor ...


Parece que tenho feito funcionar com data = list( blogs )e então json.dumps( data ). Um array sai com um monte de objetos do lado do javascript, nenhuma análise necessária.
Arthur Tarasov

3

Você não define exatamente a aparência dos dicionários, mas provavelmente está se referindo a QuerySet.values(). Da documentação oficial do Django :

Retorna a ValuesQuerySet- uma QuerySetsubclasse que retorna dicionários quando usado como iterável, em vez de objetos de instância de modelo.

Cada um desses dicionários representa um objeto, com as chaves correspondentes aos nomes dos atributos dos objetos do modelo.


2

Digite o elenco para a lista

    job_reports = JobReport.objects.filter(job_id=job_id, status=1).values('id', 'name')

    json.dumps(list(job_reports))

1

Você pode usar o values()método no dict obtido no campo do modelo do Django no qual faz as consultas e, então, pode acessar facilmente cada campo por um valor de índice.

Chame assim -

myList = dictOfSomeData.values()
itemNumberThree = myList[2] #If there's a value in that index off course...

1

Você precisa DjangoJSONEncodere listfazer o seu Querysetpara json, ref: Python JSON serializar um objeto Decimal

import json
from django.core.serializers.json import DjangoJSONEncoder


blog = Blog.objects.all().values()
json.dumps(list(blog), cls=DjangoJSONEncoder)


0

Você pode definir uma função usando model_to_dict da seguinte maneira:

def queryset_to_dict(qs,fields=None, exclude=None):
    my_array=[]
    for x in qs:
        my_array.append(model_to_dict(x,fields=fields,exclude=exclude))
    return my_array
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.