8

Djangoを使用してデータベースのテーブルを表示する必要があります。明らかな方法は、テーブルの見出しを手動で入力し、のクエリ結果をループすることですmodel.objects.all()。ただし、非常に怠惰なので、これを自動的に実行します。つまり、モデルからイントロスペクションまでのすべてのフィールドをロードして列見出しとして表示し、すべてのフィールド値をロードして行として表示します。このアプローチでは、モデルが変更されたときにテンプレートコードを更新する必要がないため、後で時間を節約することもできます。私はそれを動作させましたが、2つの問題があります:

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

2 に答える 2

6

serializers.serialize("jsonまたはxml", Model.objects.all())format は id フィールドを返します。おそらくあなたが探しているものではありませんが、jQuery グリッド プラグインの中には、タスクをさらに自動化できるものもあります。

于 2013-01-30T23:54:12.650 に答える
2

わーい!データを json にシリアル化することに関する Видул Петров の提案のおかげで、回避策を見つけました。これにより、pk フィールドもロードできます。まだ手動でハックっぽい (そして冗長) 感じがしますが、私は近づいていると思います。このコードをさらにリファクタリングするのを手伝ってください。

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>
于 2013-01-31T01:20:20.173 に答える