テンプレートのモデルインスタンスフィールド名と値を反復処理します


183

選択したインスタンスのフィールド値とその名前を表示する基本的なテンプレートを作成しようとしています。最初の列にフィールド名(フィールドで指定されている場合は特にverbose_name)を1番目の列に、そのフィールドの値を2番目の列に持つ、テーブルインスタンスのそのインスタンスの値の単なる標準出力と考えてください。

たとえば、次のモデル定義があるとします。

class Client(Model):
    name = CharField(max_length=150)
    email = EmailField(max_length=100, verbose_name="E-mail")

私はそれを次のようにテンプレートに出力したいと思います(与えられた値を持つインスタンスを想定します):

Field Name      Field Value
----------      -----------
Name            Wayne Koorts
E-mail          waynes@email.com

私が達成しようとしているのは、モデルのインスタンスをテンプレートに渡して、次のようにテンプレートで動的に反復できることです。

<table>
    {% for field in fields %}
        <tr>
            <td>{{ field.name }}</td>
            <td>{{ field.value }}</td>
        </tr>
    {% endfor %}
</table>

これを行うためのきちんとした「Django承認」方法はありますか?これは非常に一般的な作業のように思われ、この特定のプロジェクトでは頻繁に行う必要があります。

回答:


171

model._meta.get_all_field_names()モデルのすべてのフィールド名が表示されるので、を使用model._meta.get_field()して、詳細な名前を作成getattr(model_instance, 'field_name')し、モデルから値を取得できます。

注:model._meta.get_all_field_names()はdjango 1.9では非推奨です。代わりmodel._meta.get_fields()に、モデルのフィールドfield.nameを取得し、各フィールド名を取得するために使用します。


2
これはまだ非常に手作業であり、ビューにある種のメタオブジェクトを作成してテンプレートに渡さなければなりません。きっとすてきな方法があるに違いない?
ウェインコート2010年

2
ModelFormと同じように、これらすべてをクラスにカプセル化できます。
Ignacio Vazquez-Abrams

18
テンプレートで_メソッドを呼び出せるとは思いません。
Issac Kelly

2
これは機能しますが、それを実現するためにプライベートAPI(「_」で始まるため)に依存するべきではありません。プライベートAPIに依存することの問題は、プライベートメソッドがバージョン間で機能することが保証されないことです。
Devy

1
テンプレートからアンダースコアで始まる属性にアクセスするべきではないので、この方法は推奨されるべきではないと思います
GP92 '20

72

Djangoのto-pythonクエリセットシリアライザー使用できます。

次のコードをビューに配置するだけです。

from django.core import serializers
data = serializers.serialize( "python", SomeModel.objects.all() )

そして、テンプレートで:

{% for instance in data %}
    {% for field, value in instance.fields.items %}
        {{ field }}: {{ value }}
    {% endfor %}
{% endfor %}

その大きな利点は、リレーションフィールドを処理することです。

フィールドのサブセットについては、以下を試してください。

data = serializers.serialize('python', SomeModel.objects.all(), fields=('name','size'))

これはすばらしいことですが、この方法では、結果を特定のフィールドのみに制限するにはどうすればよいでしょうか。
Herman Schaaf、

2
これは決定的な答えであり、外部キーを処理し、プライベートAPI呼び出しは行いません。すばらしい答え、ありがとう。
Yunti 2015年

3
serializeを使用する必要はありません。辞書を返すquerysetvalues()メソッドを使用できます。さらに、このメソッドはサブセット化するフィールドのリストを受け入れます。リンクを参照してください。私の完全な答えを見てください。
user3062149

ループで処理するのではなく、.fieldsでのみ送信するようにこれを更新できますか?モデル/テーブル名を公開したくない
Loser Coder '13

このメソッドでverbose_nameは、フィールドのを渡すことができますか?
alias51

71

最後にこれに対する良い解決策がdevメーリングリストで見つかりました:

ビューに次を追加します。

from django.forms.models import model_to_dict

def show(request, object_id):
    object = FooForm(data=model_to_dict(Foo.objects.get(pk=object_id)))
    return render_to_response('foo/foo_detail.html', {'object': object})

テンプレートに追加:

{% for field in object %}
    <li><b>{{ field.label }}:</b> {{ field.data }}</li>
{% endfor %}

1
良い解決策ですが、ForeignKeyフィールドのmodel_to_dictではなくunicodeの結果を返すため、あまり一般的ではないため、複雑なオブジェクトをdictに簡単にシリアル化できません
Vestel

22
オブジェクトをオーバーライドするのは危険です。他のわかりやすい名前を使用してください。
EmilStenström、2012年

ありがとうございました!Djangoのmodel_to_dict()を置き換えて、ForeignKeyを処理できるようにしました。私の個別の回答を参照してください(コメントはコードのフォーマットをサポートしていないため、以前のコメントを削除しました。申し訳ありません、それを知りませんでした。)
Magnus Gustavsson 2013年

2
ここがFooFormであると仮定するとModelForm、単に行うほうが簡単ではないでしょうFooForm(instance=Foo.objects.get(pk=object_id)))か?
beruic

この方法で編集可能なフィールドのみを表示する方法はありますか?
alias51

22

Django 1.8のリリース(およびModel _meta APIの正式化)に照らして、これをより最近の回答で更新すると思いました。

同じモデルを想定:

class Client(Model):
    name = CharField(max_length=150)
    email = EmailField(max_length=100, verbose_name="E-mail")

Django <= 1.7

fields = [(f.verbose_name, f.name) for f in Client._meta.fields]
>>> fields
[(u'ID', u'id'), (u'name', u'name'), (u'E-mail', u'email')]

Django 1.8+(正式なモデル_meta API)

Django 1.8で変更:

Model _metaAPIは常にDjango内部として存在していましたが、正式には文書化されておらず、サポートされていませんでした。このAPIを公開する取り組みの一環として、既存のAPIエントリポイントの一部がわずかに変更されました。新しい公式APIを使用するようにコードを変換するのに役立つ移行ガイドが提供されています。

以下の例では、我々はのための正式な方法を利用するモデルのすべてのフィールドインスタンスの取得を経由しClient._meta.get_fields()

fields = [(f.verbose_name, f.name) for f in Client._meta.get_fields()]
>>> fields
[(u'ID', u'id'), (u'name', u'name'), (u'E-mail', u'email')]

実は、上記は必要なものに対しては少し行き過ぎであることに私の注意が向けられました(同意します!)。シンプルは複雑よりも優れています。参考までに残しておきます。ただし、テンプレートに表示するには、ModelFormを使用してインスタンスを渡すのが最善の方法です。フォームを反復処理し(フォームの各フィールドを反復処理することと同じ)、label属性を使用してモデルフィールドのverbose_nameを取得し、valueメソッドを使用して値を取得できます。

from django.forms import ModelForm
from django.shortcuts import get_object_or_404, render
from .models import Client

def my_view(request, pk):
    instance = get_object_or_404(Client, pk=pk)
    
    class ClientForm(ModelForm):
        class Meta:
            model = Client
            fields = ('name', 'email')

    form = ClientForm(instance=instance)

    return render(
        request, 
        template_name='template.html',
        {'form': form}
    )

次に、テンプレート内のフィールドをレンダリングします。

<table>
    <thead>
        {% for field in form %}
            <th>{{ field.label }}</th>
        {% endfor %}
    </thead>
    <tbody>
        <tr>
            {% for field in form %}
                <td>{{ field.value|default_if_none:'' }}</td>
            {% endfor %}
        </tr>
    </tbody>
</table>
 

2
モデルフィールドをテンプレートに配置する "> 1.8"の方法を示すように回答を調整すると、すばらしいでしょう。現時点では、あなたの答えが質問に直接答えることはありません。シェルでモデルのフィールドを取得する方法を示しています。
エッシャー

@エッシャー-答えを更新しました!提案をありがとう。何かを見落としたり、台無しにしたりした場合はお知らせください!
マイケルB

賛成。値とフィールド名を印刷するように編集しました。あなたの考えを見てください。
エッシャー

値はどこに印刷しますか?名前とverbose_nameを表示しているだけですか?
アーニー博士2016年

@MichaelBうーん。「field.value」を機能させることができませんでした。フィールドは、実際の列データではなく、データベースフィールドのように見えます。getattr(object、name)と呼ばれるフィルターを使わなければなりませんでした。Djangoのどのバージョンが動作しますか?
アーニー博士2016

19

モデルメソッドを使用した別のアプローチを次に示します。このバージョンでは、選択リスト/選択フィールドを解決し、空のフィールドをスキップして、特定のフィールドを除外できます。

def get_all_fields(self):
    """Returns a list of all field names on the instance."""
    fields = []
    for f in self._meta.fields:

        fname = f.name        
        # resolve picklists/choices, with get_xyz_display() function
        get_choice = 'get_'+fname+'_display'
        if hasattr(self, get_choice):
            value = getattr(self, get_choice)()
        else:
            try:
                value = getattr(self, fname)
            except AttributeError:
                value = None

        # only display fields with values and skip some fields entirely
        if f.editable and value and f.name not in ('id', 'status', 'workshop', 'user', 'complete') :

            fields.append(
              {
               'label':f.verbose_name, 
               'name':f.name, 
               'value':value,
              }
            )
    return fields

次に、テンプレートで:

{% for f in app.get_all_fields %}
  <dt>{{f.label|capfirst}}</dt>
    <dd>
      {{f.value|escape|urlize|linebreaks}}
    </dd>
{% endfor %}

3
なぜあなたは必要except User.DoesNotExist:ですか?
セブンアース

User.DoesNotExistの代わりにAttributeErrorを使用する傾向があります-なぜUser.DoesNotExistがスローされるのかわかりません。
askvictor 2016

また、これはdjango 1.8+で公式に公開されているので、self._meta.get_fields()を使用する方が良いかもしれません。しかし、その後、あなたはf.is_relationをチェックすることにより、フィルタリングする必要があると思います、コード内の関係、で終わる
askvictor

User.DoesNotExist(元の実装の残り)の代わりにAttributeErrorを使用するように回答を編集しました。ありがとう。_meta.get_fields()テストできるようになるまで待ちます。
シャッカー2016

13

わかりました、これは少し遅いのですが、正しい答えを見つける前にこれに出くわしたので、他の誰かがそうかもしれません。

django docsから:

# This list contains a Blog object.
>>> Blog.objects.filter(name__startswith='Beatles')
[<Blog: Beatles Blog>]

# This list contains a dictionary.
>>> Blog.objects.filter(name__startswith='Beatles').values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]

私はこの答えが好きです。クエリが複数のレコードを返し、最新のレコードのみが必要な場合は、次の操作を行います。1.あなたが持っていることを確認しますordering = ['-id']class Meta:で、あなたのオブジェクトのmodels.py。2.次に使用Blog.objects.filter(name__startswith='Beatles').values()[0]
12

賢いアイデア。しかし、すでにmodelオブジェクトがある場合は、フィールドを取得するためだけにデータベースに再度アクセスします。それを回避する方法はありますか?
frnhr 2014年

@ user1763732は、QuerySetのドキュメントを確認してください:docs.djangoproject.com/en/dev/ref/models/querysets
olofom

9

辞書を返すのvalues()メソッドを使用できますqueryset。さらに、このメソッドはサブセット化するフィールドのリストを受け入れます。このvalues()メソッドはでは機能しないget()ため、使用する必要がありますfilter()QuerySet APIを参照)。

view...

def show(request, object_id):
   object = Foo.objects.filter(id=object_id).values()[0]
   return render_to_response('detail.html', {'object': object})

detail.html...

<ul>
   {% for key, value in object.items %}
        <li><b>{{ key }}:</b> {{ value }}</li>
   {% endfor %}
</ul>

以下のためのインスタンスのコレクションフィルタによって返されました:

   object = Foo.objects.filter(id=object_id).values() # no [0]

ではdetail.html ...

{% for instance in object %}
<h1>{{ instance.id }}</h1>
<ul>
    {% for key, value in instance.items %}
        <li><b>{{ key }}:</b>  {{ value }}</li>
    {% endfor %}
</ul>
{% endfor %}

これは素晴らしいです、ありがとう!あなたが私を助けることができるかどうか、私には質問があります。私は、内のすべてのオブジェクトのデータを入れているtable私は、それぞれ必要なので、keysでth。ループなしでどうすればよいですか?オブジェクトインスタンスを取得し、それをkeysの間繰り返すだけですか?現在、個別にを渡しmodel_to_dict(Model())ていますがth、これは不要なオブジェクトのインスタンス化だと思います。
Oxwivi 2016年

素晴らしい答え。個人的には、リストビューと詳細ビューの両方でこれを使用しました。リストビューは実装するのがほぼ明らかですが、詳細ビューを使用して詳細ビューをオーバーライドget_objectします(コメントのインラインコード制限のために破損し、このスレッドの飽和度を考慮した独自の回答にはこれで十分ではありません): def get_object(self, **kwargs): obj = super().get_object(**kwargs) obj = obj.__class__.objects.filter(pk=obj.pk).values()[0] return obj
sdconrox

obj.get_absolute_url行を複製せずにこのリストにどのように追加しますか?
alias51

8

https://stackoverflow.com/a/3431104/2022534を使用しましたが、Djangoのmodel_to_dict()をこれに置き換えて、ForeignKeyを処理できるようにしました。

def model_to_dict(instance):
    data = {}
    for field in instance._meta.fields:
        data[field.name] = field.value_from_object(instance)
        if isinstance(field, ForeignKey):
            data[field.name] = field.rel.to.objects.get(pk=data[field.name])
    return data

必要のないオリジナルの部分を削除することでかなり簡略化したことに注意してください。それらを元に戻すことをお勧めします。


8

フォームに作業を任せることができます。

def my_model_view(request, mymodel_id):
    class MyModelForm(forms.ModelForm):
        class Meta:
            model = MyModel

    model = get_object_or_404(MyModel, pk=mymodel_id)
    form = MyModelForm(instance=model)
    return render(request, 'model.html', { 'form': form})

次に、テンプレートで:

<table>
    {% for field in form %}
        <tr>
            <td>{{ field.name }}</td>
            <td>{{ field.value }}</td>
        </tr>
    {% endfor %}
</table>

3
この方法(内で採用DetailView)は私にとってはうまく機能します。ただし、のfield.label代わりに使用したい場合がありfield.nameます。
David Cain

7

これを行うための組み込みの方法があるはずです。このユーティリティbuild_pretty_data_viewは、モデルオブジェクトとフォームインスタンス(モデルに基づくフォーム)を取り、を返すように作成しましたSortedDict

このソリューションの利点は次のとおりです。

  • Djangoの組み込みを使用して順序を保持しSortedDictます。
  • label / verbose_nameを取得しようとしたが、フィールド名が定義されていない場合はフィールド名にフォールバックします。
  • また、オプションでexclude()特定のフィールドを除外するためにフィールド名のリストを取得します。
  • フォームクラスにが含まれているがMeta: exclude()、それでも値を返したい場合は、それらのフィールドをオプションのappend()リストに追加します。

このソリューションを使用するには、まずこのファイル/関数をどこかに追加してから、にインポートしますviews.py

utils.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: ai ts=4 sts=4 et sw=4
from django.utils.datastructures import SortedDict


def build_pretty_data_view(form_instance, model_object, exclude=(), append=()):
    i=0
    sd=SortedDict()

    for j in append:
        try:
            sdvalue={'label':j.capitalize(),
                     'fieldvalue':model_object.__getattribute__(j)}
            sd.insert(i, j, sdvalue)
            i+=1
        except(AttributeError):
            pass

    for k,v in form_instance.fields.items():
        sdvalue={'label':"", 'fieldvalue':""}
        if not exclude.__contains__(k):
            if v.label is not None:
                sdvalue = {'label':v.label,
                           'fieldvalue': model_object.__getattribute__(k)}
            else:
                sdvalue = {'label':k,
                           'fieldvalue': model_object.__getattribute__(k)}
            sd.insert(i, k, sdvalue)
            i+=1
    return sd

だから今あなたの中でviews.pyあなたはこのようなことをするかもしれません

from django.shortcuts import render_to_response
from django.template import RequestContext
from utils import build_pretty_data_view
from models import Blog
from forms import BlogForm
.
.
def my_view(request):
   b=Blog.objects.get(pk=1)
   bf=BlogForm(instance=b)
   data=build_pretty_data_view(form_instance=bf, model_object=b,
                        exclude=('number_of_comments', 'number_of_likes'),
                        append=('user',))

   return render_to_response('my-template.html',
                          RequestContext(request,
                                         {'data':data,}))

これで、my-template.htmlテンプレートで次のようにデータを反復処理できます...

{% for field,value in data.items %}

    <p>{{ field }} : {{value.label}}: {{value.fieldvalue}}</p>

{% endfor %}

幸運を。これが誰かを助けることを願っています!


7

以下は、シャッカー に触発された私のものget_all_fieldsです。1つのモデルインスタンスのディクショナリを取得し、リレーションフィールドに遭遇した場合、フィールド値にディクショナリを再帰的に割り当てます。

def to_dict(obj, exclude=[]):
    """生成一个 dict, 递归包含一个 model instance 数据.
    """
    tree = {}
    for field in obj._meta.fields + obj._meta.many_to_many:
        if field.name in exclude or \
           '%s.%s' % (type(obj).__name__, field.name) in exclude:
            continue

        try :
            value = getattr(obj, field.name)
        except obj.DoesNotExist:
            value = None

        if type(field) in [ForeignKey, OneToOneField]:
            tree[field.name] = to_dict(value, exclude=exclude)
        elif isinstance(field, ManyToManyField):
            vs = []
            for v in value.all():
                vs.append(to_dict(v, exclude=exclude))
            tree[field.name] = vs
        elif isinstance(field, DateTimeField):
            tree[field.name] = str(value)
        elif isinstance(field, FileField):
            tree[field.name] = {'url': value.url}
        else:
            tree[field.name] = value

    return tree

この関数は主に、モデルインスタンスをjsonデータにダンプするために使用されます。

def to_json(self):
    tree = to_dict(self, exclude=('id', 'User.password'))
    return json.dumps(tree, ensure_ascii=False)

すごい仕事!選択肢を追加する提案をサポートし... elifのはhasattr(フィールド、 '選択肢'):ツリーを[field.name] = dictの(field.choices)に.get(値、値)
おでん

5

すべてのモデルを編集する代わりに、与えられたモデルのすべてのフィールドを返すテンプレートタグ1つ書くことをお勧めします。 すべてのオブジェクトにはフィールドのリストがあります。 すべてのフィールドオブジェクトには、その名前を返す属性があり、モデルで提供されるメソッドはその値を返します。 残りはDjangoのドキュメントで述べられているように単純です。
._meta.fields
namevalue_to_string()object

これは、このテンプレートタグがどのように見えるかの私の例です:

    from django.conf import settings
    from django import template

    if not getattr(settings, 'DEBUG', False):
        raise template.TemplateSyntaxError('get_fields is available only when DEBUG = True')


    register = template.Library()

    class GetFieldsNode(template.Node):
        def __init__(self, object, context_name=None):
            self.object = template.Variable(object)
            self.context_name = context_name

        def render(self, context):
            object = self.object.resolve(context)
            fields = [(field.name, field.value_to_string(object)) for field in object._meta.fields]

            if self.context_name:
                context[self.context_name] = fields
                return ''
            else:
                return fields


    @register.tag
    def get_fields(parser, token):
        bits = token.split_contents()

        if len(bits) == 4 and bits[2] == 'as':
            return GetFieldsNode(bits[1], context_name=bits[3])
        elif len(bits) == 2:
            return GetFieldsNode(bits[1])
        else:
            raise template.TemplateSyntaxError("get_fields expects a syntax of "
                           "{% get_fields <object> [as <context_name>] %}")

4

ええ、それはきれいではありません、あなた自身のラッパーを作らなければならないでしょう。本当に必要なすべての機能を備えた組み込みのdatabrowseアプリを見てください。


私は言うつもりでした... databrowseは、それを完全に役に立たないアプリであることがわかりましたが、まさにそれを行います。
mpen 2010

4

これはハックと考えられるかもしれませんが、modelform_factoryを使用してモデルインスタンスをフォームに変換する前にこれを行いました。

Formクラスには、非常に多くの情報が含まれており、繰り返し処理するのは非常に簡単で、オーバーヘッドは少し増えますが、同じ目的を果たします。セットのサイズが比較的小さい場合、パフォーマンスへの影響は無視できると思います。

もちろん、利便性以外の利点の1つは、後でテーブルを編集可能なデータグリッドに簡単に変換できることです。


4

私は次の方法を考え出しました。どの方法でもモデルにModelFormが関連付けられているため、この方法でうまくいきます。

def GetModelData(form, fields):
    """
    Extract data from the bound form model instance and return a
    dictionary that is easily usable in templates with the actual
    field verbose name as the label, e.g.

    model_data{"Address line 1": "32 Memory lane",
               "Address line 2": "Brainville",
               "Phone": "0212378492"}

    This way, the template has an ordered list that can be easily
    presented in tabular form.
    """
    model_data = {}
    for field in fields:
        model_data[form[field].label] = eval("form.data.%s" % form[field].name)
    return model_data

@login_required
def clients_view(request, client_id):
    client = Client.objects.get(id=client_id)
    form = AddClientForm(client)

    fields = ("address1", "address2", "address3", "address4",
              "phone", "fax", "mobile", "email")
    model_data = GetModelData(form, fields)

    template_vars = RequestContext(request,
        {
            "client": client,
            "model_data": model_data
        }
    )
    return render_to_response("clients-view.html", template_vars)

これは、この特定のビューに使用しているテンプレートからの抜粋です。

<table class="client-view">
    <tbody>
    {% for field, value in model_data.items %}
        <tr>
            <td class="field-name">{{ field }}</td><td>{{ value }}</td>
        </tr>
    {% endfor %}
    </tbody>
</table>

このメソッドの良い点は、テンプレートごとに、フィールドラベルを表示する順序を選択できることです。GetModelDataに渡されたタプルを使用し、フィールド名を指定します。これにより、タプルを介して渡されたフィールド名のみが最終的な辞書に組み込まれるため、特定のフィールド(ユーザー外部キーなど)を除外することもできます。

誰かがもっと「Djangonic」を思いつくことができると確信しているので、これを答えとして受け入れるつもりはありません:-)

更新:これは、私が必要とすることを行う最も単純なものであるため、これを最終的な回答として選択します。答えを提供してくれたすべての人に感謝します。


3

私のためのDjango 1.7ソリューション:

変数は質問に正確ですが、この例を詳細に分析できるはずです

ここで重要なの.__dict__は、モデルの
views.pyのほとんどを使用することです。

def display_specific(request, key):
  context = {
    'question_id':question_id,
    'client':Client.objects.get(pk=key).__dict__,
  }
  return render(request, "general_household/view_specific.html", context)

テンプレート

{% for field in gen_house %}
    {% if field != '_state' %}
        {{ gen_house|getattribute:field }}
    {% endif %}
{% endfor %}

テンプレートでは、フィルターを使用してdict
filters.pyのフィールドにアクセスしました。

@register.filter(name='getattribute')
def getattribute(value, arg):
  if value is None or arg is None:
    return ""
  try:
    return value[arg]
  except KeyError:
    return ""
  except TypeError:
    return ""

2

私はこれを使用しています、https://github.com/miracle2k/django-tables

<table>
<tr>
    {% for column in table.columns %}
    <th><a href="?sort={{ column.name_toggled }}">{{ column }}</a></th>
    {% endfor %}
</tr>
{% for row in table.rows %}
    <tr>
    {% for value in row %}
        <td>{{ value }}</td>
    {% endfor %}
    </tr>
{% endfor %}
</table>

2

このアプローチは、djangoのModelFormなどのクラスと{{form.as_table}}などのテンプレートタグを使用する方法を示していますが、すべてのテーブルはフォームではなくデータ出力のように見えます。

最初のステップは、djangoのTextInputウィジェットをサブクラス化することでした。

from django import forms
from django.utils.safestring import mark_safe
from django.forms.util import flatatt

class PlainText(forms.TextInput):
    def render(self, name, value, attrs=None):
        if value is None:
            value = ''
        final_attrs = self.build_attrs(attrs)
        return mark_safe(u'<p %s>%s</p>' % (flatatt(final_attrs),value))

次に、djangoのModelFormをサブクラス化して、デフォルトのウィジェットを読み取り専用バージョンに交換します。

from django.forms import ModelForm

class ReadOnlyModelForm(ModelForm):
    def __init__(self,*args,**kwrds):
        super(ReadOnlyModelForm,self).__init__(*args,**kwrds)
        for field in self.fields:
            if isinstance(self.fields[field].widget,forms.TextInput) or \
               isinstance(self.fields[field].widget,forms.Textarea):
                self.fields[field].widget=PlainText()
            elif isinstance(self.fields[field].widget,forms.CheckboxInput):
                self.fields[field].widget.attrs['disabled']="disabled" 

それらが私が必要とした唯一のウィジェットでした。しかし、このアイデアを他のウィジェットに拡張することは難しくありません。


1

@wonderの編集

def to_dict(obj, exclude=[]):
    tree = {}
    for field in obj._meta.fields + obj._meta.many_to_many:
        if field.name in exclude or \
           '%s.%s' % (type(obj).__name__, field.name) in exclude:
            continue
        try :
            value = getattr(obj, field.name)
        except obj.DoesNotExist as e:
            value = None
        except ObjectDoesNotExist as e:
            value = None
            continue
        if type(field) in [ForeignKey, OneToOneField]:
            tree[field.name] = to_dict(value, exclude=exclude)
        elif isinstance(field, ManyToManyField):
            vs = []
            for v in value.all():
                vs.append(to_dict(v, exclude=exclude))
            tree[field.name] = vs
        else:
            tree[field.name] = obj.serializable_value(field.name)
    return tree

Djangoに関連フィールド以外のすべてのフィールドを処理させます。より安定していると思います



0

私はシェルでこのようなものをテストしました、そしてそれは仕事をしているようです:

my_object_mapped = {attr.name: str(getattr(my_object, attr.name)) for attr in MyModel._meta.fields}

外部オブジェクトのstr()表現が必要な場合は、strメソッドで定義する必要があることに注意してください。それからあなたはオブジェクトの値の口述を持っています。次に、ある種のテンプレートなどをレンダリングできます。


0

Django> = 2.0

追加get_fields()あなたにmodels.py

class Client(Model):
    name = CharField(max_length=150)
    email = EmailField(max_length=100, verbose_name="E-mail")

    def get_fields(self):
        return [(field.verbose_name, field.value_from_object(self)) for field in self.__class__._meta.fields]

次にobject.get_fields、あなたのようにそれを呼び出しますtemplate.html

<table>
    {% for label, value in object.get_fields %}
        <tr>
            <td>{{ label }}</td>
            <td>{{ value }}</td>
        </tr>
    {% endfor %}
</table>

-1

<table border='1'>
	<tr>
		{% for mfild in fields%}
			<td>{{mfild}}</td>
		{% endfor%}
	</tr>
    {%for v in records%}
        <tr>
        	<td>{{v.id}}</td>
        	<td>{{v.title}}</td>
        	<td class="">{{v.desc}}</td>

        </tr>

    {% endfor%}
 </table>
 
 
enter code here


1
こんにちは、SOへようこそ。解答のみをコードに投稿しないでください。また、この質問にはすでに承認された回答があり、コードの形式が正しくありません。廃止されたHTML属性を使用しており、最も重要なのは、コードが承認されたものよりも優れたソリューションを提供する方法を説明していないことです。
Frieder
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.