2009-08-06 15 views
54

तो fruits में अलग सूचियों है सूची ['apples', 'oranges', 'pears'],कॉमा Django टेम्पलेट्स

वहाँ Django टेम्पलेट टैग का उपयोग "सेब, संतरा, नाशपाती और" का निर्माण करने के लिए एक त्वरित तरीका है?

मैं जानता हूँ कि यह एक पाश और {% if counter.last %} बयानों का उपयोग कर यह करने के लिए मुश्किल नहीं है, लेकिन क्योंकि मैं इस बार बार उपयोग करने के लिए जा रहा हूँ मुझे लगता है कि मैं कस्टम टैग फिल्टर लिखने के लिए कैसे जानने के लिए जा रहा हूँ, और मैं पहिया को फिर से शुरू नहीं करना चाहते हैं अगर यह पहले से ही किया जा चुका है।

एक विस्तार के रूप में, Oxford Comma (यानी "सेब, संतरे और नाशपाती") को वापस करने के मेरे प्रयासों को भी गड़बड़ है।

+2

आप मौजूदा शामिल टेम्पलेट टैग का उपयोग क्यों नहीं कर रहे हैं? –

+1

@ एसएलओटी: जब मैंने दस्तावेज़ पृष्ठ पर सूची को देखा तो मैंने टेम्पलेट टैग में शामिल नहीं किया। उफ़। ऐसा कहकर, अगला चरण सूची में प्रत्येक आइटम को हाइपरलिंक में लपेटना है, जिसके लिए मुझे लगता है कि मुझे एक फ़िल्टर लिखना होगा। – Alasdair

+0

यदि आप अपने Django यूआरएल के लिंक का उपयोग कर रहे हैं, तो आपको '{% url%} 'टैग का उपयोग करना होगा। '% {% के ​​लिए%} 'लूप अचानक और अधिक आकर्षक लग रहा है। "बार-बार" अक्सर इसका अर्थ है कि आपके टेम्पलेट्स को '{%%%}' सामान्य सुविधाओं की आवश्यकता है। –

उत्तर

30

मैं एक कस्टम Django templating फिल्टर बल्कि एक कस्टम टैग से सुझाव है। {{ fruits | joinby:", " }} मैं क्या प्रयोजन के लिए करना चाहते हैं चाहते हैं की तरह लग रहा ... एक कस्टम joinby फिल्टर के साथ:

def joinby(value, arg): 
    return arg.join(value) 

जो जैसा कि आप देख सादगी ही है!

def join_with_commas(obj_list): 
    """Takes a list of objects and returns their unicode representations, 
    seperated by commas and with 'and' between the penultimate and final items 
    For example, for a list of fruit objects: 
    [<Fruit: apples>,<Fruit: oranges>,<Fruit: pears>] -> 'apples, oranges and pears' 
    """ 
    if not obj_list: 
     return "" 
    l=len(obj_list) 
    if l==1: 
     return u"%s" % obj_list[0] 
    else:  
     return ", ".join(unicode(obj) for obj in obj_list[:l-1]) \ 
       + " and " + unicode(obj_list[l-1]) 

टेम्पलेट में इसका इस्तेमाल करने के लिए:: {{ fruits | join_with_commas }}

+0

मुझे टैग और फ़िल्टर के बीच भेद के बारे में पता नहीं था। जबकि जब मैं प्रलेखन को देखता हूं तो कस्टम टैग थोड़ा मुश्किल लगते हैं, फ़िल्टर सरल होने लगते हैं, और वास्तव में मुझे इस मामले में क्या चाहिए। धन्यवाद! – Alasdair

+5

यह अंतिम "और" सम्मिलित नहीं करता है। – Meekohi

+1

@ मीकोही, तो 'वापसी arg.join (मूल्य [: - 1]) +' और '+ मूल्य [-1] '(एपी शैली के लिए, यानी" ऑक्सफोर्ड अल्पविराम "शैली के लिए' और 'से पहले कोई अल्पविराम नहीं है, '+ 'और''' से पहले एक '+ arg' सही जोड़ें)। मैं, मैं http://yiterarydevices.net/asyndeton/ प्रति एसिंडटन की ताकत पसंद करता हूं। और अंग्रेजी शैली पर इस अच्छी बहस में से कोई भी स्टैक ओवरफ्लो पर निर्भर नहीं है - इसे अंग्रेजी.stackexchange.com पर ले जाएं! -) –

111

पहला विकल्प: मौजूदा शामिल टेम्पलेट टैग का उपयोग करें।

http://docs.djangoproject.com/en/dev/ref/templates/builtins/#join

यहाँ उनके उदाहरण

{{ value|join:" // " }} 

दूसरा विकल्प है: ध्यान में रखते हुए यह करना।

fruits_text = ", ".join(fruits) 

प्रतिपादन के लिए टेम्पलेट को fruits_text प्रदान करें। (यहाँ की तरह, जहां उपयुक्त हो) फिल्टर handier और सरल है -

+0

मुझे अन्य सूचियों (जैसे 'सब्जियां_टेक्स्ट') की आवश्यकता हो सकती है, और मैं इन सूचियों का उपयोग कई विचारों में कर सकता हूं, इसलिए मेरे पास एक समाधान होगा जिसके लिए मुझे केवल टेम्पलेट्स को बदलने की आवश्यकता है। एक कस्टम टैग लिखने के बारे में सोचने के कारणों में से एक यह है कि मैं पाइथन का उपयोग कर सकता हूं - 'जॉइन' लूप के मुकाबले निश्चित रूप से अधिक सुरुचिपूर्ण है। – Alasdair

+4

यह अंतिम "और" भी सम्मिलित नहीं करता है। – Meekohi

+0

क्या टेम्पलेट में या दृश्य में ऐसा करने के लिए कोई अच्छा अभ्यास है? – Rikki

6

यहाँ फिल्टर मैं अपने समस्या को हल करने में लिखा था है। comma.html में इस कोड डालें:

{% if not forloop.last %}{% ifequal forloop.revcounter 2 %} and {% else %}, {% endifequal %}{% else %}{% endif %} 

और अब भी आप अल्पविराम डाल चाहते हैं, "comma.html" के बदले में शामिल हैं: '।'

{% for cat in cats %} 
Kitty {{cat.name}}{% include "comma.html" %} 
{% endfor %} 
59

यहाँ एक सुपर सरल उपाय है

+6

बहुत उपयोगी। धन्यवाद! –

+3

सबसे अच्छा समाधान यदि आपको किसी सरणी – BiAiB

+0

में स्ट्रिंग्स से अधिक में शामिल होने की आवश्यकता है तो बहुत चालाक समाधान। – vmassuchetto

4

आप एक चाहते हैं माइकल मैथ्यू टूमिम के जवाब के अंत में, उपयोग करें:

{% if not forloop.last %}{% ifequal forloop.revcounter 2 %} and {% else %}, {% endifequal %}{% else %}{% endif %}{% if forloop.last %}.{% endif %} 
1

Django इस आउट ऑफ़ द बॉक्स के लिए समर्थन नहीं है। आप इस के लिए एक कस्टम फिल्टर परिभाषित कर सकते हैं: आप तार के सिर्फ सूचियों तुलना में अधिक जटिल कुछ के साथ सौदा करना चाहते हैं

from django import template 


register = template.Library() 


@register.filter 
def join_and(value): 
    """Given a list of strings, format them with commas and spaces, but 
    with 'and' at the end. 

    >>> join_and(['apples', 'oranges', 'pears']) 
    "apples, oranges, and pears" 

    """ 
    # convert numbers to strings 
    value = [str(item) for item in value] 

    if len(value) == 1: 
     return value[0] 

    # join all but the last element 
    all_but_last = ", ".join(value[:-1]) 
    return "%s, and %s" % (all_but_last, value[-1]) 

हालांकि, आप अपने टेम्पलेट में स्पष्ट {% for x in y %} पाश का उपयोग करना होगा।

0

आप एक-लाइनर्स पसंद है:

@register.filter 
def lineup(ls): return ', '.join(ls[:-1])+' and '+ls[-1] if len(ls)>1 else ls[0] 

और फिर टेम्पलेट में:

{{ fruits|lineup }} 
13

Django टेम्पलेट पर यह सब आप प्रत्येक फल के बाद एक अल्पविराम की स्थापना के लिए क्या करने की जरूरत। आखिरी फल पहुंचने के बाद कॉमा रुक जाएगा।

{% if not forloop.last %}, {% endif %} 
+1

बहुत साफ और आसान समाधान। – SaeX

संबंधित मुद्दे