2009-07-09 15 views
98

की वर्बोज़ संस्करण मैं एक मॉडल है:Django टेम्पलेट्स: एक विकल्प

from django.db import models 

CHOICES = (
    ('s', 'Glorious spam'), 
    ('e', 'Fabulous eggs'), 
) 

class MealOrder(models.Model): 
    meal = models.CharField(max_length=8, choices=CHOICES) 

मैं एक रूप है:

from django.forms import ModelForm 

class MealOrderForm(ModelForm): 
    class Meta: 
     model = MealOrder 

और मैं formtools.preview उपयोग करना चाहते हैं। डिफ़ॉल्ट टेम्पलेट, विकल्प ('शानदार अंडे' के स्थान पर 'ई') का लघु संस्करण प्रिंट क्योंकि यह

{% for field in form %} 
<tr> 
<th>{{ field.label }}:</th> 
<td>{{ field.data }}</td> 
</tr> 
{% endfor %}. 

का उपयोग करता है के रूप में उल्लेख मैं जनरल के रूप में एक टेम्पलेट चाहते हैं, लेकिन मुद्रण 'शानदार अंडे ' बजाय।

[के रूप में मैं संदेह था जहां असली सवाल है, मैं यह हम सभी के लिए बोल्ड :)]

मुझे पता है कि एक तरह से खुद को बदसूरत है कि में एक विकल्प के वर्बोज़ संस्करण प्राप्त करने के:

{{ form.meal.field.choices.1.1 }} 

असली दर्द मेरे द्वारा चुने गए विकल्प प्राप्त करने की आवश्यकता है, और एक ही तरीका है मेरे मन में आने के विकल्प के माध्यम से पुनरावृत्ति और {% ifequals currentChoice.0 choiceField.data %}, जो भी भद्दा है जाँच कर रहा है।

क्या यह आसानी से किया जा सकता है? या इसे कुछ टेम्पलेट टैग प्रोग्रामिंग की आवश्यकता है? क्या यह पहले से ही django में उपलब्ध नहीं होना चाहिए?

उत्तर

4

मुझे नहीं लगता कि ऐसा करने के लिए कोई अंतर्निहित तरीका है। एक फिल्टर चाल है, हालांकि कर सकते हैं:

@register.filter(name='display') 
def display_value(bf): 
    """Returns the display value of a BoundField""" 
    return dict(bf.field.choices).get(bf.data, '') 

तो फिर तुम कर सकते हैं:

{% for field in form %} 
    <tr> 
     <th>{{ field.label }}:</th> 
     <td>{{ field.data|display }}</td> 
    </tr> 
{% endfor %} 
208

Django में टेम्पलेट्स आप "get_FOO_display()" विधि, उस क्षेत्र के लिए पठनीय उर्फ ​​वापस आ जाएगी उपयोग कर सकते हैं, जहां 'फू' क्षेत्र का नाम है।

नोट: यदि मानक FormPreview टेम्पलेट्स इसका उपयोग नहीं कर रहे हैं, तो आप उस फॉर्म के लिए हमेशा provide your own templates कर सकते हैं, जिसमें {{ form.get_meal_display }} जैसे कुछ शामिल होंगे।

#annoyances/templatetags/data_verbose.py 
from django import template 

register = template.Library() 

@register.filter 
def data_verbose(boundField): 
    """ 
    Returns field's data or it's verbose version 
    for a field with choices defined. 

    Usage:: 

     {% load data_verbose %} 
     {{form.some_field|data_verbose}} 
    """ 
    data = boundField.data 
    field = boundField.field 
    return hasattr(field, 'choices') and dict(field.choices).get(data,'') or data 

मुझे यकीन है कि मौसम यह इस तरह के प्रयोजन के लिए एक फिल्टर का उपयोग करने के लिए ठीक है नहीं कर रहा हूँ:

+1

हाँ, मुझे पता है। यह सामान्य (सार्वभौमिक) के रूप में नहीं है, हालांकि - जब तक आप एक मॉडल ऑब्जेक्ट के सभी get_FOO_display विधियों पर टेम्पलेट में पुन: प्रयास करने का कोई तरीका नहीं जानते हैं :) मैं गैर-जेनेरिक टेम्पलेट्स लिखने के लिए थोड़ा आलसी हूं;) इसके अलावा, दस्तावेज़ कहते हैं कि यह एक मॉडल उदाहरण विधि है। इसलिए इसे एक मौजूदा वस्तु से बंधे मॉडल मॉडल होना चाहिए जो मामला नहीं है और सामान्य भी नहीं है। –

+0

मैं इसे भूल रहा हूं – Sevenearths

+2

ध्यान दें कि यह उपयोग विचारों तक ही सीमित नहीं है, get_FOO_display() मॉडल ऑब्जेक्ट पर एक विधि है ताकि आप इसे मॉडल कोड में भी उपयोग कर सकें! उदाहरण के लिए, __unicode __() में यह आपके पथ # परेशानियों/templatetags/... LOL का उल्लेख करने के लिए – Bogatyr

9

नोआ जबाब के आधार पर, यहाँ विकल्प के बिना क्षेत्रों के लिए एक संस्करण प्रतिरक्षा है। अगर किसी के पास बेहतर समाधान है, तो मुझे यह देखकर खुशी होगी :) धन्यवाद नोहा!

+0

+1 बहुत आसान है ... मैं get_FOO_display() का उपयोग करता हूं, जिसे फॉर्म डॉक्स के नीचे उल्लिखित किया गया है। –

+0

विकल्पों पर हैट्टर के उपयोग के साथ महान विचार! – oden

6

हम डेटा और फ़ील्ड प्रकार से निपटने में अधिक सार्वभौमिक होने की Noah द्वारा फिल्टर समाधान का विस्तार कर सकते हैं:

#app_name/templatetags/custom_tags.py 
def human_readable(value, arg): 
    if hasattr(value, 'get_' + str(arg) + '_display'): 
     return getattr(value, 'get_%s_display' % arg)() 
    elif hasattr(value, str(arg)): 
     if callable(getattr(value, str(arg))): 
      return getattr(value, arg)() 
     else: 
      return getattr(value, arg) 
    else: 
     try: 
      return value[arg] 
     except KeyError: 
      return settings.TEMPLATE_STRING_IF_INVALID 
register.filter('human_readable', human_readable) 
+0

काफी सार्वभौमिक लगता है :) निश्चित रूप से नहीं बता सकता, क्योंकि मैंने उस समय से बहुत अधिक पायथन या Django नहीं किया है। हालांकि, यह बहुत दुखद है कि इसे अभी भी एक तीसरी पार्टी (Django में शामिल नहीं है) फ़िल्टर की आवश्यकता है (अन्यथा आप हमें बताएंगे, इवान, क्या आप नहीं करेंगे?)) ... –

+0

@ArturGajowy हां, के रूप में आज Django में ऐसी कोई डिफ़ॉल्ट सुविधा नहीं है। मैंने इसका प्रस्ताव दिया है, [कौन जानता है, शायद इसे मंजूरी दे दी जाएगी] (https://groups.google.com/group/django-developers/browse_thread/thread/9ff2222931b381c7)। –

35

आपकी समस्या के लिए सबसे अच्छा समाधान के लिए है:

<table> 
{% for item in query %} 
    <tr> 
     {% for field in fields %} 
      <td>{{item|human_readable:field}}</td> 
     {% endfor %} 
    </tr> 
{% endfor %} 
</table> 

कोड यह सहायक कार्यों का उपयोग करें। विकल्पों चर विकल्प और मॉडल फ़ील्ड चयनित विकल्प भंडारण है 'विकल्पों' में जमा हो जाती है, तो आप सीधे

{{ x.get_choices_display }} 

उपयोग कर सकते हैं अपने खाके में। यहां, एक्स मॉडल उदाहरण है। उम्मीद है कि यह मदद करता है।

+3

उपयोगी उत्तर पहले से ही होने के बाद आप इस 2 साल की तरह क्यों जवाब देंगे? और इसे वोट कौन करेगा? यह 2 साल बाद @ रॉबर्टो के समान जवाब है .... – boatcoder

+10

@ Mark0978 इस उत्तर को ऊपर उठाने का कारण यह है क्योंकि (मेरे लिए) यह "शीर्ष वोट" उत्तर का पालन करने के लिए स्पष्ट था। YMMV। –

2

अपने models.py करने के लिए एक सरल समारोह जोड़ें:

def get_display(key, list): 
    d = dict(list) 
    if key in d: 
     return d[key] 
    return None 

अब, आप ऐसे ही चुनाव क्षेत्रों में वर्बोज़ मूल्य प्राप्त कर सकते हैं:

class MealOrder(models.Model): 
    meal = models.CharField(max_length=8, choices=CHOICES) 

    def meal_verbose(self): 
     return get_display(self.meal, CHOICES)  

Upd .: मुझे यकीन है कि नहीं हूँ, वह समाधान "पायथनिक" और "django-way" पर्याप्त है या नहीं, लेकिन यह काम करता है। :)

25

मेरी क्षमा है अगर यह उत्तर ऊपर सूचीबद्ध किसी भी के साथ अनावश्यक है, लेकिन ऐसा लगता है कि यह अभी तक पेश नहीं किया गया है, और यह काफी साफ लगता है।

from django.db import models 

class Scoop(models.Model): 
    FLAVOR_CHOICES = [ 
     ('c', 'Chocolate'), 
     ('v', 'Vanilla'), 
    ] 

    flavor = models.CharField(choices=FLAVOR_CHOICES) 

    def flavor_verbose(self): 
     return dict(Scoop.FLAVOR_CHOCIES)[self.flavor] 

मेरा विचार (ध्यान दें: नहीं Scoop.values ​​()) टेम्पलेट के लिए एक स्कूप से गुजरता है:, और टेम्पलेट शामिल हैं:

{{ scoop.flavor_verbose }} 
+0

धन्यवाद :) यह वही था जो मैं ढूंढ रहा था। –

-2
साथ

यहाँ मैं यह कैसे हल किया गया है एक टेम्पलेट टैग का उपयोग।

लगभग आर्थर गजोज के समान ही है, लेकिन यह उन विकल्पों के लिए है जो केवल स्ट्रिंग के बजाय इंटीजर मानों का उपयोग करते हैं।

# project/templatetags/project_tags.py 

from django.template.base import Library 


register = Library() 

@register.filter(name='pretty_form_value') 
def pretty_form_value(field): 
    """ 
    Returns field's data or it's verbose version 
    for a field with choices defined. 

    Usage:: 

     {% load project_tags %} 
     {{form.some_field|pretty_form_value}} 
    """ 
    if hasattr(field.field, 'choices'): 
     try: 
      return dict(field.field.choices)[int(field.data)] 
     except ValueError: 
      pass 
    return field.data 
संबंधित मुद्दे