显示对象django表

时间:2013-01-30 23:30:26

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

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

  1. 我无法找到加载AutoField字段(id)的值,所以我必须切掉ID列。
  2. 代码看起来非常混乱,特别是使用随机模板标签。
  3. 这是我的代码。请注意,代码工作正常,因此我将跳过所有导入,因为它们是正确的:

      

    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]
    

3 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:5)

看看这应该从你的模型中为你自动化很多这个。 http://django-tables2.readthedocs.org/en/latest/

答案 2 :(得分: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>