简体   繁体   中英

How to combine a QuerySet and a Dictionary in Django Template?

I have Django an model object that looks like this:

class myObj(models.Model):
    A = models.TextField()
    B = models.DateField()      
    C = models.ForeignKey(User)

I am obtaining a querySet of myObjs like this:

mList = myObj.objects.all()

I also have a dictionary of Users that looks like this:

uDict = {1: "Hello", 2: "World"}  //The keys of this dictionary correspond to the field myObj.C

In my view I am sending both the mList and the uList to my HTML template using the Context.

In my template, I would like to list all the mLists on separate lines. Those mLists that have a matching User entry in the uDict should appear with the matching value from the uList.

How should I do this? In the template I can easily iterate through the mList. But I don't know how to match the myObj.C to the uDict key. I know that this won't work:

{% for currObj in mList %}
    {{currObj.A}} {{currObj.B}} {{uDict.currObj.C}}
{% endfor %} 

... because uDict.currObj.C won't evaluate correctly.

So what's the best way to do what I'm trying to do?

You can't use a for loop variable as a key to a dictionary in Django unfortunately.

What you can do is package them all in some list or other data set. Something like this:

mList = myObj.objects.all()
uDict = {1: "Hello", 2: "World"}

data_for_template = []
for i in range(len(mList)):
    data_for_template.append(
        {
            'mListObjA':mList.A,
            'mListObjB':mList.B,
            'uDictObj':uDict[i], # or i+1 for your example uDict
        }
    )

Then in your template you'll be able to access this data in a similar fashion.

{% for item in data_for_template %}
    {{item.mListObjA}} {{item.mListObjB}} {{item.uDictObj}}
{% endfor %}

Essentially you should try and do most of the prep work for your data in your views.py file to simplify the accessibility in the template.

EDIT:

Something I would try next, in light of your comment:

views.py:

mList = myObj.objects.all()
uDict = {1: "Hello", 2: "World"}

data_for_template = []
for i in range(len(mList)):
    data_for_template.append(
        {
            'mListObj':mList,
            'uDictObj':uDict[i], # or i+1 for your example uDict
        }
    )

html

{% for item in data_for_template %}
    {{item.mListObj.A}} {{item.mListObj.B}} {{item.uDictObj}}
    {{item.mListObj.C.F.G}}
{% endfor %}

{{data_for_template.N.mListObj.C.F.G}} <!-- Where N is the index of whatever Object you wish to access -->

I think the simplest approach is to add the uDict values directly to the myObj instances in your view. This will give you a list rather than a qs in the context, but that shouldn't make any difference in your template.

In your view:

mList = myObj.objects.all()
for my_obj in mList:
    my_obj.user = uDict.get(my_obj.C)

This adds the user values to the in-memory instances, so in the template you can get currObj.user .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM