【问题标题】:Display table of objects django显示对象表 django
【发布时间】:2013-01-14 23:13:48
【问题描述】:

我需要使用 Django 从我的数据库中显示一个表。显而易见的方法是手动输入表格标题并循环遍历model.objects.all() 的查询结果。但是,由于非常懒惰,我想自动执行此操作,即通过自省从模型中加载所有字段以显示为列标题,并加载所有字段值以显示为行。这种方法还可以为我节省一些时间,因为我不必在模型更改时更新我的​​模板代码。我得到它的工作,但有两个问题:

  1. 我找不到加载 AutoField 字段 (id) 值的方法,所以我必须切掉 ID 列。
  2. 代码看起来很乱,尤其是在使用随机模板标签时。

这是我的代码。请注意,代码运行良好,因此我将跳过所有正确的导入:

views.py 我使用序列化程序来序列化数据,这是我在 stackoverflow 某处读到的技巧

def index(request):
   fields    = MyModel._meta.fields
   data      = serializers.serialize("python", MyModel.objects.all())
   context_instance = RequestContext(request, {    
       'data'      : data,
       'fields'    : fields,
   })
   return TemplateResponse(request, 'index.html', context_instance)

template/index.html:请注意,我必须通过切掉字段列表的第一个元素来切掉 ID 列

{% with fields|slice:"1:" as cached_fields %}
<table>
    <thead>
        <tr>
            {% for field in cached_fields %}
                <th>{% get_verbose_name field %}</th>
            {% endfor %}
        </tr>
    </thead>
    <tbody>
        {% for instance in data %}
        <tr>
            {% for field in cached_fields %}
                <td>{% get_value_from_key instance.fields field %}</td>
            {% endfor %}
        </tr>
        {% endfor %}
    </tbody>
</table>
{% endwith %}

templatetags/extra_tags.py

# tag to get field's verbose name in template 
@register.simple_tag
def get_verbose_name(object):
    return object.verbose_name

# tag to get the value of a field by name in template
@register.simple_tag
def get_value_from_key(object, key):
    # is it necessary to check isinstance(object, dict) here? 
    return object[key.name]

【问题讨论】:

    标签: python django django-models django-templates django-views


    【解决方案1】:

    serializers.serialize("jsonxml", Model.objects.all())格式返回id字段;可能不是您想要的,但一些 jQuery 网格插件可以进一步自动化任务。

    【讨论】:

    • 感谢您的输入,但在这里包含 JS 对我来说有点矫枉过正。
    • 不客气。如果我正确理解了有关 AutoField 的问题:可以像这样过滤它:filter(lambda x: not x.auto_created, MyModel._meta.fields).
    • 请看我的新答案,告诉我你的想法:) 我听从你关于使用 json 的建议。
    【解决方案2】:

    耶!感谢 Видул Петров 关于将数据序列化为 json 的建议,我找到了解决方法,这也允许我加载 pk 字段。它仍然感觉过于手动和hackish(和冗长),但我想我已经接近了。请帮助我进一步重构此代码。

    views.py 将数据序列化为 JSON 对象列表并将其解析为字典列表以将其传递给模板

    from django.utils import simplejson as json    
    
    def index(request):
       fields    = MyModel._meta.fields
       data      = json.loads(serializers.serialize("json", MyModel.objects.all()))
    
       def parse_data(data):
    
            result = [] 
    
            # flatten the dictionary
            def flatten_dict(d):
                """ 
                Because the only nested dict here is the fields, let's just
                remove the 'fields' suffix so that the fields can be loaded in 
                template by name
                """
                def items():
                    for key, value in d.items():
                        if isinstance(value, dict):
                            for subkey, subvalue in flatten_dict(value).items():
                                yield subkey, subvalue
                        else:
                            yield key, value
    
                return dict(items())
    
            for d in data:
                # change the 'pk' key name into its actual name in the database
                d[Employee._meta.pk.name] = d.pop('pk') 
                # append the flattend dict of each object's field-value to the result 
                result.append(flatten_dict(d))
    
            return result
    
    
       context_instance = RequestContext(request, {    
           'data'      : parse_data(data),
           'fields'    : fields,
       })
       return TemplateResponse(request, 'index.html', context_instance)
    

    template/index.html模板现在好多了

    <table>
        <thead>
            <tr>
                {% for field in cached_fields %}
                    <th>{% get_verbose_name field %}</th>
                {% endfor %}
            </tr>
        </thead>
        <tbody>            
                {% for d in data %}
                    <tr>
                        {% for field in fields %}
                            <td>{% get_value_from_key d field %}</td>
                        {% endfor %}
                    </tr>
                {% endfor %}            
        </tbody>
    </table>
    

    【讨论】:

    • FWIW,不久前我尝试做类似的事情,这比我的版本少手动和hacky。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-20
    相关资源
    最近更新 更多