0

I want to pass data from my view to my template in an efficient way. Specifically I need an array with a dict inside of it like so:

arraydict = [{key:value}, {key:value} ...]

Right now this is what I do:

class VisualizationView(ListView):
    template_name = 'visualize.html'
    model = UrlTime

    def get_context_data(self, **kwargs):
        context = super(VisualizationView, self).get_context_data(**kwargs)
        #Extracts the months and counts them
        context['months'] = (UrlTime.objects.annotate(month=ExtractMonth('timestamp')).values('month').annotate(c=Count('id')))

this counts my months. Printing our my {{ month }} in my django template gives me back this queryset:

<QuerySet [{'month': 5, 'c': 313}, {'month': 6, 'c': 1961}]>

So far so good. My idea is to visualize my data with d3.js for which I need well-strucutred data. So I would like to transform this queryset into something like:

data = [{5:313}, {6:1961}]. Basically creating a dict of the values of the queryset and then put it into an array.

(Even better would be data = [{May:313}, {June:1961}])

I tried the .values() method which breaks my count method. Also I tried to put it into a list like so:

list(UrlTime.objects.annotate(month=ExtractMonth('timestamp')).values('month').annotate(c=Count('id'))) (this works but gives me back a list with dict of keys and arrays like so: [{'month': 5, 'c': 313}, {'month': 6, 'c': 1962}]

I also did some looping in my template, yet my idea is to put most of the logic into my view, so I'd prefer the code outside the template.

Is there an easy way to do this or am I on the wrong track? Any help is very much appreciated. Thanks in advance.

Micromegas
  • 1,499
  • 2
  • 20
  • 49
  • I'm not sure what you're asking. You can convert that queryset to JSON just with `json.dumps()`. – Daniel Roseman Jun 19 '19 at 07:52
  • thank you Daniel. Well at the end I want to work with the data in a javascript file. I try to do all the logic in the view first. Then I pass it to my template and from there I get it to a js file. The answers below do answer exactly what I wanted. But would you say that converting the data to JSON is the better way to go? – Micromegas Jun 19 '19 at 11:26

2 Answers2

1

as i got from your question you have this: [{'month': 5, 'c': 313}, {'month': 6, 'c': 1962}] and need this :[{5:313}, {6:1961}] thus :

initial_data = [{'month': 5, 'c': 313}, {'month': 6, 'c': 1962}]
data = []
list_item ={}
for items in initial_data:
    month = items['month']
    count =items['c']
    list_item[month] = count
    data.append(list_item)
    list_item = {}

for change month number to name of month you need to create a converter function and replace the value

user907988
  • 625
  • 1
  • 5
  • 17
1

You can refactor your data like that :

data = []

for item in the_list: #list is your initial datas format as python list
    tmp_dict = {}
    tmp_dict[item['month']] = item['c']
    data.append(tmp_dict)

print(data)

For the date, you have this topic that explains well : Get month name from number

BastienB
  • 180
  • 2
  • 14