Queryset to list python

How to Convert a Django Queryset into List of Dicts

How do I convert a Django QuerySet into list of dicts?

>>> Blog.objects.values()
[],
>>> Blog.objects.values('id', 'name')
[]

Note: the result is a QuerySet which mostly behaves like a list, but isn’t actually an instance of list . Use list(Blog.objects.values(…)) if you really need an instance of list .

get dictionary from queryset

Build a list of dicts with model instance.title as key and the specs as value by iterating over all Environment model instances.

[ for i in Environment.objects.all()]

Python/Django QuerySet to list of dicts?

other_objs[0] will be the first element of query and will not be a dict or string but the django model object, you can access attributes like other_objs[0].myattr1 , if you want dict you can ask for specifc attributes using objects.values_list and then create a dict out of them e.g.

attrs = ['id', 'attr1']
values = Object1.objects.values_list(attrs)[0]
obj_dict = dict(zip(attrs, values))

or you can use django serialization is you want to output dict or json etc, but I think you just need an object, and original query is sufficient.

Читайте также:  Npm css minimizer webpack plugin

Convert QuerySet into List in Django for ModelMultipleChoiceField

from django.utils.translation import gettext_lazy as _

class Appointment(models.Model):

class TimeSlot(models.TextChoices):
FIRST_T = '5', _('9:00 - 09:30')
SECOND_T = '9', _('09:30 - 10:00')
THIRD_T = '2', _('10:00 - 10:30')

time_slot = models.CharField(max_length=1,choices=TimeSlot.choices,default=TimeSlot.FIRST_T)


class AvailabilitiesForm(forms.Form):
time_slot = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple)

def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
d1 = kwargs.pop('date')
ava_time = []

for i in Appointment.objects.filter(date=d1):
for x in Appointment.TimeSlot.choices:
if x[0] == i.time_slot:
ava_time.append(x)

self.fields['time_slot'].choices = ava_time

Convert Django Model object to dict with all of the fields intact

There are many ways to convert an instance to a dictionary, with varying degrees of corner case handling and closeness to the desired result.

, 
'_state': ,
'auto_now_add': datetime.datetime(2018, 12, 20, 21, 34, 29, 494827, tzinfo=),
'foreign_key_id': 2,
'id': 1,
'normal_value': 1,
'readonly_value': 2>

This is by far the simplest, but is missing many_to_many , foreign_key is misnamed, and it has two unwanted extra things in it.

from django.forms.models import model_to_dict
model_to_dict(instance)
 'id': 1, 
'many_to_many': [],
'normal_value': 1>

This is the only one with many_to_many , but is missing the uneditable fields.

from django.forms.models import model_to_dict
model_to_dict(instance, fields=[field.name for field in instance._meta.fields])

This is strictly worse than the standard model_to_dict invocation.

SomeModel.objects.filter(id=instance.id).values()[0]
), 
'foreign_key_id': 2,
'id': 1,
'normal_value': 1,
'readonly_value': 2>

This is the same output as instance.__dict__ but without the extra fields.
foreign_key_id is still wrong and many_to_many is still missing.

The code for django’s model_to_dict had most of the answer. It explicitly removed non-editable fields, so removing that check and getting the ids of foreign keys for many to many fields results in the following code which behaves as desired:

from itertools import chain

def to_dict(instance):
opts = instance._meta
data = <>
for f in chain(opts.concrete_fields, opts.private_fields):
data[f.name] = f.value_from_object(instance)
for f in opts.many_to_many:
data[f.name] = [i.id for i in f.value_from_object(instance)]
return data

While this is the most complicated option, calling to_dict(instance) gives us exactly the desired result:

), 
'foreign_key': 2,
'id': 1,
'many_to_many': [2],
'normal_value': 1,
'readonly_value': 2>

Django Rest Framework’s ModelSerializer allows you to build a serializer automatically from a model.

from rest_framework import serializers
class SomeModelSerializer(serializers.ModelSerializer):
class Meta:
model = SomeModel
fields = "__all__"

SomeModelSerializer(instance).data
 'foreign_key': 2, 
'id': 1,
'many_to_many': [2],
'normal_value': 1,
'readonly_value': 2>

This is almost as good as the custom function, but auto_now_add is a string instead of a datetime object.

Bonus Round: better model printing

If you want a django model that has a better python command-line display, have your models child-class the following:

from django.db import models
from itertools import chain

class PrintableModel(models.Model):
def __repr__(self):
return str(self.to_dict())

def to_dict(instance):
opts = instance._meta
data = <>
for f in chain(opts.concrete_fields, opts.private_fields):
data[f.name] = f.value_from_object(instance)
for f in opts.many_to_many:
data[f.name] = [i.id for i in f.value_from_object(instance)]
return data

class Meta:
abstract = True

So, for example, if we define our models as such:

class OtherModel(PrintableModel): pass

class SomeModel(PrintableModel):
normal_value = models.IntegerField()
readonly_value = models.IntegerField(editable=False)
auto_now_add = models.DateTimeField(auto_now_add=True)
foreign_key = models.ForeignKey(OtherModel, related_name="ref1")
many_to_many = models.ManyToManyField(OtherModel, related_name="ref2")

Calling SomeModel.objects.first() now gives output like this:

), 
'foreign_key': 2,
'id': 1,
'many_to_many': [2],
'normal_value': 1,
'readonly_value': 2>

Источник

Convert a django queryset to list

Convert a django queryset to list

Convert a django queryset to list

While working with Django queryset, at some point you need more than just a queryset object type like converting a queryset to a list.

Django queryset can be converted to a list using the python’s built-in list method (list(queryset.objects.all())) but note that it is not ideal to load the whole result into memory via list() in terms of memory and time optimization.

Let’s cover other approaches we can work to convert django queryset to list.

Join this free python and django newsletter to learn more about python and django.

Django queryset to list using list() method

Python’s built-in list() method to convert a queryset to a list is not an optimized approach as this will load all the objects in your memory.

from apps.blog.models import * articles = Blog.objects.all() # This will return a queryset type print(type(articles)) # Convert articles queryset to a python's list type articles_list = list(articles) # This will return a list type print(type(articles_list)) 

Django Queryset to list using values_list() method

Django’s built-in model.objects.values_list() method is one of the ideal ways of converting a queryset to a list.

It returns tuples when iterated over. Each tuple contains the value from the respective field or expression passed into the values_list(). For example:

from apps.blog.models import Blog articles = Blog.objects.values_list() print(articles) print(list(articles)) 
>]>)]> [(26, 'List of useful websites for software engineers', 5, 'list-useful-websites-software-engineers', None, datetime.date(2022, 3, 3), datetime.date(2022, 4, 20), 18, 'List of useful websites for software engineers', '', None, 1, True, >]>)] 

If you only want single values in a list, then you have to pass a single field and a flat parameter set as True.

from apps.blog.models import Blog articles = Blog.objects.values_list('id',flat=True) print(articles) print(list(articles)) 

If you want multiple values in a list, then you have to pass multiple arguments in values_list().

from apps.blog.models import Blog articles = Blog.objects.values_list('id','category') print(articles) print(list(articles)) 

If you want to read about Django queryset in detail then I want you to go through this guide on Django ORM in detail.

Join this free python and django newsletter to learn more about python and django.

Did you find this article valuable?

Support Nitin Raturi by becoming a sponsor. Any amount is appreciated!

Источник

Django Queryset To List In Detail

While working with Django queries, sometimes we need to convert the django queryset to list or dictionary.

Django queryset to list using list() method.

I know you are thinking that we can easily convert it using the python list() function. And yes you are thinking right. But here is one problem, converting queryset using list() function is not an efficient way. It takes more time and memory.

from app.models import Book books = Book.objects.all() # it will convert the queryset into list # but it is not efficient and will take more memory book_list = list(books) # Output: [, ] for book in book_list: print(book.name) # Output: # Django for APIs # Beginning Django E-Commerce 

So let’s talk about Django’s provided way to convert django queryset to list i.e values_list()

This is our simple Book model which I will use in this article.

#models.py class Book(models.Model): name = models.CharField('Book name', max_length=100) author = models.ForeignKey(Author, on_delete=models.CASCADE) published = models.DateField('Published') categories = models.ManyToManyField(Category) def __str__(self): return self.name

Django queryset to list using values_list() method.

value_list() is a django builtin method to convert django queryset to list and it’s ideal medthod.

We will discuss each parameter in detail

It returns tuples when iterated over. Each tuple contains the value from the respective field or expression passed into the values_list() call.

from app.models import Book books = Book.objects.all().values_list() books

You can also pass your required fields that you want to convert into the list.

For example, I want to get ids and author names only.

books = Book.objects.all().values_list('id','author__name') books

Let’s talk about flat attribute of values_list()

While converting queryset to list, If you want single values in a list, not a list of tuples. Then you have to pass the single field in a values_list() and flat=True.

# When flat = True books = Book.objects.all().values_list('id', flat=True) books # Output #
# When flat = False books = Book.objects.all().values_list('id') books # Output: #

Note: It is an error to pass in flat=True when there is more than one field. You will get following error: TypeError: ‘flat’ is not valid when values_list is called with more than one field.

Let’s talk about named attribute of values_list().

While converting queryset to list, currently, we are getting results like this but if you also want to get the field name like then you can set named = True.

books = Book.objects.all().values_list('id', 'author__name', named=True) books

Using a named tuple may make use of the results more readable, at the expense of a small performance penalty for transforming the results into a named tuple. source: Django documentation

Note: ‘flat’ and ‘named’ can’t be used together. You will get following error: TypeError: ‘flat’ and ‘named’ can’t be used together.

Get() method with values_list()

You can get a specific field value of a certain model instance by using values_list() followed by get() function.

books = Book.objects.all().values_list('name', 'author__name').get(pk=1) books
('Django for APIs', 'William S. Vincent')

That’s all. If you find it useful then show some love and support by clapping or by buying me coffee. And don’t forget to share it with your friends. In case of any problem, you can comment here or you can also directly approach me through my LinkedIn.

Related Article.

I would greatly appreciate it if you subscribe to my YouTube channel, Let’s Code More

Источник

Оцените статью