在渲染模板时去掉字典键的引号

3 投票
4 回答
3345 浏览
提问于 2025-04-17 21:04

在使用render_to_string函数渲染一个字典时,有没有办法去掉键的引号,这样我在模板中得到的就是key:value,而不是'key':value呢?

比如说,如果我的字典是这样的:

d = {'a':1, 'b':2}

然后我这样渲染它,

return render_to_string('somefile.json', {'d':d})

那么在somefile.json中,我会看到{{d}}变成了{'a':1, 'b':2},但我希望{{d}}显示为{a:1, b:2}。(也就是没有引号)

我该怎么做才能实现这个呢?

谢谢!

4 个回答

0

我觉得约翰的解决方案很有用,稍微调整了一下他的代码,以适应我的情况。目的是让字典中的所有值都加上引号,而字典中的键则不加引号。

{
  "variant": {
    "id": 808950810,
    "option1": "Not Pink",
    "price": "99.00"
  }
}

为了

{variant:{id:'32036302848074', compare_at_price:'39.83'}}
class DictWithoutQuotedKeys(dict):
    def __repr__(self):
        s = "{"
        for key in self:
            s += "{0}:".format(key)
            # if isinstance(self[key], str):
            #     # String values still get quoted
            #     s += "\"{0}\", ".format(self[key])
            # if isinstance(self[key], int):
            #     # String values still get quoted
            #     s += "\'{0}\', ".format(self[key])

            if isinstance(self[key], dict):
                # Apply formatting recursively
                s += "{0}, ".format(DictWithoutQuotedKeys(self[key]))
            else:
                # Quote all the values
                s += "\'{0}\', ".format(self[key])
        if len(s) > 1:
            s = s[0: -2]
        s += "}"
        return s
1

我对代码进行了调整,以处理嵌套的列表和字典。
代码如下:

class DictWithoutQuotedKeys(dict):
def __repr__(self):
   # print(self)
    s = "{"
    
    for key in self:
        s += "{0}:".format(key)
        if isinstance(self[key], dict):
            # Apply formatting recursively
            s += "{0}, ".format(DictWithoutQuotedKeys(self[key]))
        elif isinstance(self[key], list):
            s +="["
            for l in self[key]:
                if isinstance(l, dict):
                    s += "{0}, ".format(DictWithoutQuotedKeys(l))
                else:
                    #print(l)
                    if isinstance(l, int):
                        s += "{0}, ".format(l)
                    else:
                        s += "'{0}', ".format(l)
            if len(s) > 1:
                s = s[0: -2]
            s += "], "
        else:
            if isinstance(self[key], int):
                s += "{0}, ".format(self[key])
            else:
                s += "\'{0}\', ".format(self[key])
            # Quote all the values
            #s += "\'{0}\', ".format(self[key])
    
    if len(s) > 1:
        s = s[0: -2]
    s += "}"
    return s

输入:

data = {'a':["1", "3", 4], 'b':[{'check1':9, 'check2':"kkk"}], 'c': {'d':2 , 'e': 3}, 'f':'dd', 't':2}

输出:

{a:['1', '3', 4], b:[{check1:9, check2:'kkk'}], c:{d:2, e:3}, f:'dd', t:2}
1

我觉得Stepan的回答很准确,也很有用。在我的情况下,递归地应用渲染,并且在字符串元素上保留引号,这样做也很有帮助。这个扩展版本可能对其他人也有用:

class DictWithoutQuotedKeys(dict):
    def __repr__(self):
        s = "{"
        for key in self:
            s += "{0}:".format(key)
            if isinstance(self[key], basestring):
                # String values still get quoted
                s += "\"{0}\", ".format(self[key])
            elif isinstance(self[key], dict):
                # Apply formatting recursively
                s += "{0}, ".format(DictWithoutQuotedKeys(self[key]))
            else:
                s += "{0}, ".format(self[key])
        if len(s) > 1:
            s = s[0: -2]
        s += "}"
        return s
3

你可以尝试一种方法,就是重写 dict 类的 __repr__ 方法,或者创建一个它的子类并在里面修改这个方法。下面我给你提供了后者的解决方案。

class MyDict(dict):
    def __repr__(self):
        s = "{"
        for key in self:
            s += "{0}:{1}, ".format(key, self[key])
        if len(s) > 1:
            s = s[0: -2]
        s += "}"
        return s

MyDict({'a': 1, 'b': 2})
{a:1, b:2}

撰写回答