टेम्पलेट में मॉडल उदाहरण क्षेत्र के नाम और मानों पर फेरबदल करें


183

मैं चयनित नामों के फ़ील्ड मानों को उनके नाम के साथ प्रदर्शित करने के लिए एक मूल टेम्पलेट बनाने का प्रयास कर रहा हूं। पहले कॉलम में फ़ील्ड नाम (क्रिया विशेष रूप से यदि फ़ील्ड पर निर्दिष्ट) और दूसरे कॉलम में उस फ़ील्ड के मान के साथ तालिका उदाहरण में उस उदाहरण के मानों के मानक आउटपुट के रूप में सोचें।

उदाहरण के लिए, मान लें कि हमारे पास निम्नलिखित मॉडल परिभाषा है:

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
यह अभी भी बहुत ही मैनुअल है, और मुझे उस दृश्य में किसी प्रकार की मेटा ऑब्जेक्ट का निर्माण करना होगा, जिसे मैं तब टेम्पलेट में पास करता हूं, जो कि मेरी पसंद से अधिक हैक है। निश्चित रूप से वहाँ एक रास्ता होना चाहिए?
वेन कोर्ट्स

2
आप यह सब एक वर्ग में कर सकते हैं, जैसे कि मॉडलफ़ॉर्म करता है।
इग्नासियो वाज़केज़-अब्राम्स

18
मुझे विश्वास नहीं होता कि आप किसी भी तरीके को टेम्पलेट में कह सकते हैं।
इस्साक केली

2
यह काम करता है लेकिन आपको इसे प्राप्त करने के लिए एक निजी एपीआई पर निर्भर नहीं होना चाहिए (क्योंकि यह "_" के साथ उपसर्ग करता है)। निजी एपीआई पर निर्भर होने के साथ समस्या यह है कि निजी तरीकों को संस्करण से संस्करण तक काम करने की गारंटी नहीं है।
देवी

1
मुझे लगता है कि इस पद्धति को प्राथमिकता नहीं दी जानी चाहिए क्योंकि हम टेम्प्लेट से अंडरस्कोर से शुरू होने वाली विशेषताओं तक पहुंच नहीं होनी चाहिए
GP92

72

आप Django के पायथन क्वेरीसेट सीराइज़र का उपयोग कर सकते हैं ।

निम्नलिखित कोड को अपने विचार में रखें:

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

यह अच्छा है - लेकिन इस विधि के साथ, कोई केवल कुछ क्षेत्रों के परिणामों को कैसे सीमित करेगा?
हरमन शेफ

2
यह निश्चित उत्तर होना चाहिए, विदेशी कुंजी संभालता है और कोई निजी एपीआई कॉल नहीं करता है। शानदार जवाब, धन्यवाद।
युंति

3
यह क्रमबद्ध उपयोग करने के लिए आवश्यक नहीं है। आप क्वेरी के मान () विधि का उपयोग कर सकते हैं , जो एक शब्दकोश देता है। इसके अलावा, इस पद्धति से उप-फ़ील्ड की एक सूची स्वीकार की जाती है। देखें लिंक । देखिए मेरा पूरा जवाब।
user3062149

क्या हम इसे लूप में प्रोसेस करने के बजाय केवल .fields में भेज सकते हैं? मैं मॉडल / टेबल के नामों को उजागर नहीं करना चाहता हूं
कोडर

क्या यह विधि verbose_nameक्षेत्र को पारित करने की अनुमति देती है?
अलिसा ५१

70

अंत में देव मेलिंग सूची में इसका एक अच्छा समाधान मिला :

दृश्य में जोड़ें:

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
अच्छा समाधान है, लेकिन बहुत सामान्य नहीं है क्योंकि यह विदेश के खेतों के लिए एक model_to_dict नहीं है, लेकिन यूनिकोड का परिणाम देता है, इसलिए आप जटिल वस्तु को आसान नहीं बना सकते हैं
Vestel

22
ऑब्जेक्ट को ओवरराइड करने के लिए खतरनाक, आपको कुछ अन्य वैरायबल नाम का उपयोग करना चाहिए।
एमिल स्टेनस्ट्रॉम

धन्यवाद! मैंने Django के model_to_dict () को विदेशीके को संभालने में सक्षम होने के लिए प्रतिस्थापित किया। कृपया मेरा अलग उत्तर देखें (मैंने अपनी पिछली टिप्पणी हटा दी है क्योंकि टिप्पणियाँ कोड स्वरूपण का समर्थन नहीं करती हैं। क्षमा करें, मुझे यह नहीं पता था।)
मैग्नस गुस्तावसन

2
यहाँ यह मानते हुए कि FooFormएक है ModelForm, नहीं यह सिर्फ करने के लिए आसान हो: FooForm(instance=Foo.objects.get(pk=object_id)))?
बेरिक

कोई भी विचार कि आप इस विधि के साथ केवल संपादन योग्य फ़ील्ड कैसे प्रदर्शित करेंगे?
अलिअस ५१

22

Django 1.8 की रिलीज (और मॉडल _meta एपीआई की औपचारिकता के प्रकाश में) , मुझे लगा कि मैं इसे और अधिक जवाब के साथ अपडेट करूंगा।

उसी मॉडल को मानते हुए:

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 में परिवर्तित:

मॉडल _metaएपीआई हमेशा एक 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')]

वास्तव में, यह मेरे ध्यान में लाया गया है कि ऊपर जो जरूरत थी उसके लिए थोड़ा ओवरबोर्ड है (मैं सहमत हूं!)। सरल जटिल से बेहतर है। मैं संदर्भ के लिए ऊपर जा रहा हूं। हालांकि, टेम्पलेट में प्रदर्शित करने के लिए, सबसे अच्छा तरीका एक मॉडलफ़ॉर्म का उपयोग करना होगा और एक उदाहरण में पास होगा। आप प्रपत्र (प्रत्येक प्रपत्र के फ़ील्ड पर पुनरावृत्ति के बराबर) पर पुन: प्रसारित कर सकते हैं और मॉडल फ़ील्ड के वर्बोज़_नाम को पुनः प्राप्त करने के लिए लेबल विशेषता का उपयोग कर सकते हैं, और मान प्राप्त करने के लिए मूल्य विधि का उपयोग कर सकते हैं:

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" तरीके दिखाने के लिए अपना उत्तर समायोजित करेंगे। फिलहाल आपका जवाब सीधे सवाल का जवाब नहीं देता है; यह दिखाता है कि शेल में मॉडल के क्षेत्र कैसे प्राप्त करें।
Escher

@ ईशर - जवाब अपडेट करें! सलाह के लिये धन्यवाद। मुझे पता है अगर मैं कुछ भी याद किया / कुछ भी गड़बड़!
माइकल बी

Upvoted। मैंने मानों को मुद्रित करने के साथ-साथ फ़ील्ड नामों को भी शामिल किया। देखिये आप क्या सोचते हैं।
एस्चर

आप मूल्य कहां से छापते हैं? मैं इसे केवल नाम और verbose_name छापते हुए देखता हूं?
डॉ। एर्नी

@ मिचेलबी हम्म। मुझे काम करने के लिए "फ़ील्ड.वल्यू" नहीं मिला है; फ़ील्ड डेटाबेस फ़ील्ड प्रतीत होते हैं, वास्तविक स्तंभ डेटा नहीं। मुझे एक फिल्टर का उपयोग करना था जिसे गेटैट्र (वस्तु, नाम) कहा जाता है। Django का कौन सा संस्करण आपके लिए काम करता है?
डॉ। एर्नी

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:?
सातवार्ता

मैं UserDoesNotExist के बजाय AttributeError का उपयोग करने के लिए इच्छुक हूँ - मैं नहीं देख सकता कि यह User.DoesNotExist क्यों फेंकेगा।
प्रश्नकर्ता

इसके अलावा, self._meta.get_fields () का उपयोग करना बेहतर हो सकता है क्योंकि यह आधिकारिक तौर पर django 1.8+ में सामने आया है। हालाँकि, फिर आप कोड में संबंधों के साथ समाप्त हो जाते हैं, जिसे आपको f.is_relation
askvictor

मैंने User.DoesNotExist (जो मेरे मूल कार्यान्वयन से एक बचा हुआ था) के बजाय AttributeError का उपयोग करने का उत्तर संपादित किया है। धन्यवाद। _meta.get_fields()जब तक मैं इसका परीक्षण कर सकता हूं, मैं इसे रोक रहा हूं ।
5

13

ठीक है, मुझे पता है कि यह थोड़ा देर से है, लेकिन जब से मैं सही जवाब खोजने से पहले इस पर ठोकर खाई, तो कोई और हो सकता है।

से Django डॉक्स :

# 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]
सेवेनथर्थ

चतुर विचार। लेकिन अगर आपके पास पहले से कोई modelवस्तु है, तो आप केवल फ़ील्ड प्राप्त करने के लिए डेटाबेस को फिर से मारेंगे। उस के आसपास कोई रास्ता?
fr:

@ user1763732 केवल क्वेरीस के लिए दस्तावेजों की जांच करें: docs.djangoproject.com/en/dev/ref/models/querysets
olofom

9

आप values()एक की विधि का उपयोग कर सकते हैं queryset, जो एक शब्दकोश देता है। इसके अलावा, इस पद्धति से उप-फ़ील्ड की एक सूची स्वीकार की जाती है। values()विधि के साथ काम नहीं करेंगे get(), तो आप का उपयोग करना चाहिए filter()(का उल्लेख क्वेरीसमूह एपीआई )।

में 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, इसलिए मुझे प्रत्येक keyएस की आवश्यकता है th। मैं बिना छोरों के कैसे करूं? बस किसी भी वस्तु उदाहरण ले और keyएस के लिए इसके माध्यम से पुनरावृति ? वर्तमान में मैं अलग से गुजर रहा हूँ model_to_dict(Model())के लिए thहै, लेकिन मुझे लगता है कि यह एक अनावश्यक वस्तु इन्स्टेन्शियशन है।
ऑक्सीविवि

शानदार जवाब। व्यक्तिगत रूप से, मैंने इसका उपयोग एक सूची दृश्य और विस्तार से देखने के लिए किया। सूची दृश्य को लागू करने के लिए काफी हद तक स्पष्ट है, लेकिन विस्तार से देखने के साथ मैं विस्तार के दृश्य 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पंक्तियों की नक़ल किए बिना आप इस सूची में कैसे जुड़ेंगे?
उपनाम

8

मैंने https://stackoverflow.com/a/3431104/2022534 का उपयोग किया, लेकिन इसके साथ Django के मॉडल_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
डेविड कैन

7

ऐसा करने के लिए वास्तव में एक अंतर्निहित तरीका होना चाहिए। मैंने यह उपयोगिता लिखी है build_pretty_data_viewकि एक मॉडल ऑब्जेक्ट और फॉर्म उदाहरण (आपके मॉडल के आधार पर एक फॉर्म) लेता है और एक रिटर्न देता है SortedDict

इस समाधान के लाभों में शामिल हैं:

  • यह Django के बिल्ट-इन का उपयोग करके ऑर्डर को संरक्षित करता है SortedDict
  • जब लेबल / 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। यह एक मॉडल उदाहरण के एक तानाशाह हो जाता है, अगर मुठभेड़ संबंध क्षेत्र है, तो पुनरावर्ती रूप से फ़ील्ड मान को असाइन करें।

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 (मूल्य, मूल्य)
Oden

5

हर मॉडल को संपादित करने के बजाय मैं एक टेम्प्लेट टैग लिखने की सलाह दूंगा, जो दिए गए किसी भी मॉडल के सभी क्षेत्र को वापस कर देगा ।
प्रत्येक वस्तु में खेतों की सूची होती है ._meta.fields
प्रत्येक फ़ील्ड ऑब्जेक्ट में वह विशेषता होती है nameजो उसके नाम और पद्धति value_to_string()को लौटाएगी जो आपके मॉडल के साथ आपूर्ति की जाती है और objectउसका मान लौटाएगा।
बाकी सब उतना ही सरल है जितना कि Django के दस्तावेज में बताया गया है ।

यहाँ मेरा उदाहरण है कि यह टेम्प्लेटेटाग कैसा दिख सकता है:

    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

हाँ, यह सुंदर नहीं है, आपको अपना खुद का रैपर बनाना होगा। बिल्टिन डेटाब्रोस ऐप पर एक नज़र डालें , जिसमें सभी कार्यक्षमताएं हैं जिनकी आपको वास्तव में आवश्यकता है।


मैं कहने जा रहा था .... डेटब्रोसे बस इतना करता है, यद्यपि मैंने पाया कि यह पूरी तरह से बेकार ऐप है।
एमपीएन

4

यह एक हैक माना जा सकता है, लेकिन मैंने एक मॉडल उदाहरण को प्रपत्र में बदलने के लिए modelform_factory का उपयोग करने से पहले ऐसा किया है।

फॉर्म क्लास में बहुत अधिक जानकारी होती है, जो सुपर ओवर इटरेट करने के लिए आसान है और यह थोड़ा अधिक ओवरहेड की कीमत पर उसी उद्देश्य को पूरा करेगा। यदि आपके निर्धारित आकार अपेक्षाकृत छोटे हैं, तो मुझे लगता है कि प्रदर्शन प्रभाव नगण्य होगा।

पाठ्यक्रम की सुविधा के अलावा एक फायदा यह है कि आप बाद की तारीख में आसानी से संपादन योग्य डेटाग्रिड में तालिका को बदल सकते हैं।


4

मैं निम्नलिखित विधि के साथ आया हूं, जो मेरे लिए काम करती है क्योंकि हर मामले में मॉडल के साथ एक मॉडलफ़ॉर्म जुड़ा होगा।

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>

इस पद्धति के बारे में अच्छी बात यह है कि मैं टेम्पलेट-बाय-टेम्प्लेट के आधार पर उस क्रम को चुन सकता हूं जिसमें मैं फ़ील्ड लेबल प्रदर्शित करना चाहूंगा, गेटमॉडलडैटा में पारित टपल का उपयोग करके और फ़ील्ड नामों को निर्दिष्ट करना। यह मुझे कुछ फ़ील्ड्स (जैसे एक उपयोगकर्ता विदेशी कुंजी) को बाहर करने की भी अनुमति देता है क्योंकि केवल ट्यूल के माध्यम से पारित किए गए फ़ील्ड नामों को अंतिम शब्दकोश में बनाया गया है।

मैं इसे उत्तर के रूप में स्वीकार नहीं करने जा रहा हूं क्योंकि मुझे यकीन है कि कोई और "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 %}

टेम्प्लेट में मैंने फ़िल्टर फिल्टर का उपयोग
तानाशाह के क्षेत्र में करने के लिए किया है :

@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
नमस्ते और एसओ में आपका स्वागत है। कृपया कोड केवल उत्तर पोस्ट न करें। इस प्रश्न का भी पहले से ही एक स्वीकृत उत्तर है, आपका कोड स्वरूपण सही नहीं है, आप पदावनत html विशेषताओं का उपयोग कर रहे हैं और सबसे महत्वपूर्ण: आप यह नहीं समझा रहे हैं कि आपका कोड स्वीकृत एक से बेहतर समाधान कैसे प्रदान करता है।
फ्रीडर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.