显示对象django的表 [英] Display table of objects django

查看:103
本文介绍了显示对象django的表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


  1. 我找不到加载AutoField字段(id)值,所以我

  2. 代码看起来相当凌乱,特别是使用随机模板标签。

这是我的代码。请注意,代码工作正常,所以我将跳过所有导入,因为它们是正确的:


views.py 我使用serializer来序列化数据,我在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 :note我必须通过切除字段列表的第一个元素来分隔ID列。






  {%with fields | slice:1:as cached_fields%} 
< table>
< thead>
< tr>
{%for cached_fields%}
< th> {%get_verbose_name field%}< / th>
{%endfor%}
< / tr>
< / thead>
< tbody>
{%,例如数据%}
< tr>
{%for cached_fields%}
< td> {%get_value_from_key instance.fields field%}< / td>
{%endfor%}
< / tr>
{%endfor%}
< / tbody>
< / table>
{%endwith%}




templatetags / extra_tags.py






 #标签在模板中获取字段的详细名称
@ register.simple_tag
def get_verbose_name(object):
return object.verbose_name

#标签以获取字段的值在模板中的名称
@ register.simple_tag
def get_value_from_key(object,key):
#需要在这里检查isinstance(object,dict)吗?
return object [key.name]


解决方案

好极了!我找到了一个工作,感谢ВидулПетров关于将数据序列化到json的建议,这也允许我加载pk字段。它仍然感觉手动和黑客(和详细),但我认为我越来越近了。请帮助我进一步重构这个代码。


views.py 将数据序列化到JSON对象列表中,并将其解析为要传递的字典列表它到模板






 从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) :

因为这里唯一的嵌套字体是字段,我们只需
删除'fields'后缀,这样字段可以通过$

def items():
为键,d.items()中的值:
如果isinstance(value,dict):
用于子项,子():
产生子项,子值
else:
yield key,value

return dict(items())

数据中的d:
#将'pk'密钥名称更改为数据库中的实际名称
d [Employee._meta.pk.name] = d.pop('pk ')
#将每个对象的字段值的flattend dict附加到结果
result.append(flatten_dict(d))

返回结果


context_instance = RequestContext(request,{
'data':parse_data(data),
'fields':fields,
})
return TemplateResponse(request, 'index.html',context_instance)




模板/索引.html 现在,模板更好一些






 <表&克吨; 
< thead>
< tr>
{%for cached_fields%}
< th> {%get_verbose_name field%}< / th>
{%endfor%}
< / tr>
< / thead>
< tbody>
{%d中的数据%}
< tr>
{%字段中的字段%}
< td> {%get_value_from_key d字段%}< / td>
{%endfor%}
< / tr>
{%endfor%}
< / tbody>
< / table>


I need to display a table from my database with Django. The obvious way is to manually type in the table headings and loop through query results of model.objects.all(). However, being quite lazy, I want to do this automatically, i.e. load all fields from model through introspection to display as column headings and load all field values to display as rows. This approach can also save me some time later because I don't have to update my template code when my model changes. I got it to work but there are two problems:

  1. I can't find away to load the AutoField field (id) value so I have to slice off the ID column.
  2. The code looks quite messy especially with the use of random template tags.

Here is my code. Please note that the code works fine so I'll skip all the imports as they are correct:

views.py I use serializers to serialize the data, a trick I read somewhere on 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: note that I have to slice off the ID column by slicing off the first element of the fields list

{% 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]

解决方案

Yay! I found a work around thanks to Видул Петров's suggestion about serializing the data to json, which allows me to load the pk field as well. It still feels too manual and hackish (and verbose) but I think I'm getting close. Please help me refactor this code further.

views.py Serialize data into a list of JSON objects and parse it into a list of dictionaries to pass it to template

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 The template is much nicer now

<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>

这篇关于显示对象django的表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆