0

I'm passing a bunch of data into my template but am having a hard time breaking apart a zipped list of items. No matter what I try, I always get the following error.

Need 2 values to unpack in for loop; got 0.

Heres my code:

views.py

import requests
from django.shortcuts import render
from django.http import HttpResponse

dictionary, words = [[], []], []


def home(request, username='johnny'):
    template_name = 'main/index.html'
    url = "https://www.duolingo.com/users/{}".format(username)
    getUserData(url)
    context = {
        'username': username,
        'dictionary': dictionary,
        'words': words,
    }
    # print(context)
    return render(request, template_name, context)


def getUserData(url):
    response = requests.get(url)
    userdata = response.json()
    wordlists, explanations = [], []

    for language in userdata['language_data']:
        for index in userdata['language_data'][language]['skills']:
            if index.get('levels_finished') > 0:
                wordList = index.get("words")
                wordlists.append(wordList)
                explanations.append(index.get("explanation"))
                for wordItem in wordList:
                    words.append(wordItem)
    dictionary = list(zip(wordlists, explanations))

relevant template

{% block content %}
    {% for words, exp in dictionary %}
      {{ words }}
      {{ exp|safe }}
    {% endfor %}
{% endblock %}

I've tested this code, it works.

enter image description here

Once I refactored in Django to put wordLists in an array with explanations, things go to hell. If I print(dictionary) at the end of the method, the data shows in the console. Not sure what else I'm missing.

addohm
  • 2,248
  • 3
  • 14
  • 40

1 Answers1

2

Your problem is with scope. the dictionary(variable) which you are returning from home function(as context) and dictionary in getUserData function are not in same scope. So whenever you are updating getUserData method's dictionary, its not being updated in home. I would not recommend your approach for dictionary as its using global variable. I would recommend something like this:

def getUserData(url):
    response = requests.get(url)
    userdata = response.json()
    wordlists, explanations, words = [], [], []

    for language in userdata['language_data']:
        for index in userdata['language_data'][language]['skills']:
            if index.get('levels_finished') > 0:
                wordList = index.get("words")
                wordlists.append(wordList)
                explanations.append(index.get("explanation"))
                for wordItem in wordList:
                    words.append(wordItem)
    return list(zip(wordlists, explanations)), words  # return the value of dictionary from here


def home(request, username='johnny'):
    template_name = 'main/index.html'
    url = "https://www.duolingo.com/users/{}".format(username)
    dictionary, words = getUserData(url)  # catch value of dictionary
    context = {
        'username': username,
        'dictionary': dictionary,
        'words': words,
    }
    # print(context)
    return render(request, template_name, context)
addohm
  • 2,248
  • 3
  • 14
  • 40
ruddra
  • 50,746
  • 7
  • 78
  • 101
  • I realize my code is neither pythonic or best practice. I threw it together to see if a rough product creates inspiration. Thanks. I'll work on it some more using your suggestions. – addohm Feb 01 '19 at 11:27
  • Made a small change but it seems to work. Got a pesky json decoder error now though. lol – addohm Feb 01 '19 at 13:03