Convert query to Python list


I want to convert this query Clientes.objects.values() in a list to later use the Chartkick graphs but with the values that it returns to me.

The Clientes model is:

class Clientes(models.Model):
    Nombre = models.CharField(max_length=50,null=False)
    medio = models.ForeignKey(Medio,null=True,blank=True)

    def __unicode__(self):
        return self.Nombre

And what I want is that using Chartkick send me the number of people depending on the field medio , it should be mentioned that the media are dynamic as well as the number of people.

asked by Angel 28.03.2016 в 17:59

3 answers


Well, to start you can use a simple search with django in your client model:


The filter function filters all the objects in the model according to the search you need, the count function counts all the objects found in that search.

For more information you can use the documentation: Filter in Django

Now, you need to use chartkick what you want is to create a dictionary with the names of each medium and a number of clients of each medium, for this you can make a list or an arrangement with all the names of the media , or failing that, do a search to find the existing media in the client, and then do an iteration that creates an arrangement with the name of said medium and as a value the search that I put before you, can be in the following manner:

var data = []
for medio in medios:
    data.append(medio, Clientes.objects.filter(medio=medio).count()))

Assuming that data will be the list of data that the library will use, as it says in its documentation: [[' Chrome ', 52.9], [' Firefox ', 27.7], [' Opera ', 1.6]]

We create a media list that will have the name of the medium as objects, and in an iteration we will add to the data list the average value obtained in media and the number of objects that the media list has.

Broadly speaking, it should be a solution of that style. The last step would be to call the list generated from Django, but for this you can use this list in a class-based view as an additional context.

For this we can see the Sample List View in the documentation:

def get_context_data(self, **kwargs):
        context = super(ArticleListView, self).get_context_data(**kwargs)
        context['now'] =
        return context

In this function we can add the additional content that we want the template to show on the screen:

def get_context_data(self, **kwargs):
        context = super(ArticleListView, self).get_context_data(**kwargs)
        var data = []
        for medio in medios:
            data.append(medio, Clientes.objects.filter(medio=medio).count()))
        context['data'] = data
        return context

With this we will pass the variable data as the context data in the list view, or if you want, in a detailed view, and that would be enough.

answered by 28.03.2016 / 18:07

I understand that what you want is some kind of graph in which you have the number of clients in between. If that is the case then what you should do is group them.

To group them, I think that in this case the simplest thing would be to start from the inverse, that is, from the model Medio . Using the method annotate and Count we can count the number of clients that each medium has:

>>> data = Medio.objects.annotate(total=Count('clientes')).values_list('nombre', 'total')
[('MEDIO1', 10), ('MEDIO2', 20), ('MEDIO3', 30)]

Keep in mind that I'm using values_list instead of values to represent the results through tuples. I'm also assuming that your model Medio has a field nombre .

According to the documentation I see in the repository of Chartkick , the data can be a dictionary or a list:

{'Chrome': 52.9, 'Opera': 1.6, 'Firefox': 27.7}

[['Chrome', 52.9], ['Firefox', 27.7], ['Opera', 1.6]]

I do not know if Chartkick accepts a list of tuples but we better make sure and convert it to a list of lists:

>>> data = Medio.objects.annotate(total=Count('clientes')).values_list('nombre', 'total')
[('MEDIO1', 10), ('MEDIO2', 20), ('MEDIO3', 30)]
>>> data = [list(elem) for elem in data]
[['MEDIO1', 10], ['MEDIO2', 20], ['MEDIO3', 30]]

I think with this you already have the data ready to pass it to Chartkick.

answered by 28.03.2016 в 18:56

Sorry now they are asking me to filter by dates, I Require Day, MEs, 3 Months before, etc, Checking the documentation of Chartkick I see that it would work a range but how can I include what I already have

def charts(request):
data = Clasificacion.objects.annotate(total=Count('carros')).values_list('nombre','total',).order_by('-total')
data = [list(elem) for elem in data]
library = {
        "backgroundColor": "#FFF",
        "colors": ['#21333a','#76b5cd','#436775','#548192','#659bb0']
template = 'templates/Usuarios/Reporte_Cliente.html'
return render(request, template, locals())      

and in my client model I added the corresponding field

timestamp = models.DateTimeField(auto_now=True,)
answered by 18.04.2016 в 23:17