किसी Django टेम्पलेट में संबंधित आइटम सॉर्ट करना


87

क्या डीजेंगो टेम्पलेट में संबंधित वस्तुओं के एक सेट को छांटना संभव है?

वह है: यह कोड (HTML टैग के साथ स्पष्टता के लिए छोड़ा गया):

{% for event in eventsCollection %}
   {{ event.location }}
   {% for attendee in event.attendee_set.all %}
     {{ attendee.first_name }} {{ attendee.last_name }}
   {% endfor %}
 {% endfor %}

लगभग बिल्कुल मैं चाहता हूँ प्रदर्शित करता है । केवल एक चीज जिसे मैं बदलना चाहता हूं, मैं अंतिम नाम के आधार पर छांटे जाने वाले प्रतिभागियों की सूची है। मैंने ऐसा कुछ कहने की कोशिश की है:

{% for event in events %}
   {{ event.location }}
   {% for attendee in event.attendee_set.order_by__last_name %}
     {{ attendee.first_name }} {{ attendee.last_name }}
   {% endfor %}
 {% endfor %}

काश, उपरोक्त सिंटैक्स काम नहीं करता (यह एक खाली सूची का उत्पादन करता है) और न ही किसी भी अन्य भिन्नता के बारे में मैंने सोचा है (बहुत से वाक्यविन्यास त्रुटियों की रिपोर्ट की गई है, लेकिन कोई खुशी नहीं)।

मैं, निश्चित रूप से, मेरे विचार में कुछ प्रकार के छांटे गए सहभागी सूचियों का उत्पादन कर सकता हूं, लेकिन यह एक बदसूरत और नाजुक है (और क्या मैंने बदसूरत उल्लेख किया है) समाधान।

कहने की जरूरत नहीं है, लेकिन मैं इसे वैसे भी कहूंगा, मैंने ऑन-लाइन डॉक्स का दुरुपयोग किया है और स्टैक ओवरफ्लो और django-user के अभिलेखागार को कुछ भी उपयोगी पाए बिना (आह, अगर केवल एक क्वेरी सेट एक डिक्शनरी डिकोर्टॉर्ट करेंगे नौकरी, लेकिन यह नहीं है और यह नहीं है)

==============================================

तवामास के उत्तर को स्वीकार करने के बाद अतिरिक्त विचार जोड़ने का संपादन किया।


तवामास ने इस मुद्दे को ठीक उसी तरह संबोधित किया जैसा मैंने प्रस्तुत किया था - हालाँकि समाधान वह नहीं था जिसकी मुझे उम्मीद थी। परिणामस्वरूप मैंने एक उपयोगी तकनीक सीखी जिसका उपयोग अन्य स्थितियों में भी किया जा सकता है।

टॉम के जवाब ने एक दृष्टिकोण का प्रस्ताव दिया जिसे मैंने पहले ही अपने ओपी में उल्लेख किया था और "बदसूरत" के रूप में अस्थायी रूप से खारिज कर दिया था।

"बदसूरत" एक आंत प्रतिक्रिया थी, और मैं स्पष्ट करना चाहता था कि इसके साथ क्या गलत था। ऐसा करने में मुझे एहसास हुआ कि इसका कारण यह एक बदसूरत दृष्टिकोण था क्योंकि मैं एक क्वेरी सेट को पारित करने के विचार पर लटका दिया गया था। अगर मैं उस आवश्यकता को पूरा करता हूं, तो एक बदसूरत दृष्टिकोण है जो काम करना चाहिए।

मैंने अभी तक यह कोशिश नहीं की है, लेकिन मान लीजिए कि क्वेरीसेट को पास करने के बजाय, व्यू कोड को क्वेरी सेट के माध्यम से पुनरावृत्त किया गया, जो ईवेंट की एक सूची का निर्माण करता है, फिर प्रत्येक ईवेंट को संबंधित उपस्थितियों के लिए एक क्वेरी सेट के साथ सजाया गया, जिसे WAS सॉर्ट किया गया था (या फ़िल्टर किया गया था) या जो भी) वांछित तरीके से। कुछ इस तरह:

eventCollection = []   
events = Event.object.[filtered and sorted to taste]
for event in events:
   event.attendee_list = event.attendee_set.[filtered and sorted to taste]
   eventCollection.append(event)

अब टेम्प्लेट बन जाता है:

{% for event in events %}
   {{ event.location }}
   {% for attendee in event.attendee_list %}
     {{ attendee.first_name }} {{ attendee.last_name }}
   {% endfor %}
 {% endfor %}

नकारात्मक पक्ष यह है कि सभी घटनाओं को एक ही बार में "वास्तविक" करना है जो कि बड़ी संख्या में होने वाली घटनाओं के कारण एक समस्या हो सकती है। बेशक कोई भी जोड़-तोड़ कर सकता है, लेकिन इससे दृश्य काफी जटिल हो जाता है।

उल्टा "डेटा को प्रदर्शित करने के लिए तैयार करें" कोड उस दृश्य में है जहां वह टेम्पलेट को प्रदर्शन के लिए दृश्य द्वारा प्रदान किए गए डेटा को प्रारूपित करने पर ध्यान केंद्रित करने देता है। यह सही और उचित है।

इसलिए मेरी योजना बड़े तालिकाओं के लिए तवामास तकनीक और छोटी तालिकाओं के लिए उपरोक्त तकनीक का उपयोग करना है, जिसमें पाठक को बड़ी और छोटी छोड़ दी गई है (मुस्कराहट)।

जवाबों:


135

आपको इस तरह से सहभागी मॉडल में आदेश निर्दिष्ट करने की आवश्यकता है। उदाहरण के लिए (अपने मॉडल वर्ग का नाम अटेंडी रखा गया है):

class Attendee(models.Model):
    class Meta:
        ordering = ['last_name']

आगे के संदर्भ के लिए मैनुअल देखें ।

संपादित करें । एक अन्य उपाय अपने इवेंट मॉडल में एक संपत्ति जोड़ना है, जिसे आप अपने टेम्पलेट से एक्सेस कर सकते हैं:

class Event(models.Model):
# ...
@property
def sorted_attendee_set(self):
    return self.attendee_set.order_by('last_name')

आप इनमें से अधिक को परिभाषित कर सकते हैं क्योंकि आपको उनकी आवश्यकता है ...


आपकी टिप्पणी के लिए धन्यवाद, लेकिन यह केवल तभी काम करता है जब मैं प्रदर्शन ऑर्डर को सहभागी की स्थायी संपत्ति बनाना चाहता हूं, जो मैं नहीं करता हूं। उदाहरण के लिए, मैं चाह सकता हूं कि जब उनका पंजीकरण प्राप्त हो, तो तारीख के आधार पर छोड़े गए सहभागियों को प्रदर्शित करें, इसलिए मुझे पता होगा कि किन उपस्थितियों को सूचित किया जाना चाहिए कि उनके लिए कोई जगह नहीं थी।
डेल विल्सन

मैंने आपके लिए एक वैकल्पिक समाधान जोड़ा। यह आपको आपकी आवश्यकता के लचीलेपन की अनुमति देनी चाहिए।
तवामास

@ मार्क वास्तव में यह करता है। जहां तक ​​मैं समझता हूं कि @propertyयहां ओवरकिल है क्योंकि इसमें कोई
गेटर्स

हालांकि टेम्प्लेट के लिए कड़ाई की आवश्यकता नहीं है, मुझे लगता है कि यहां @property एप्लिकेशन कोड से क्लीनर एक्सेस के लिए बनाता है , हालांकि इसमें एक छोटा प्रदर्शन दंड शामिल है (मेरे लैपटॉप पर 30 ns)। यह निश्चित रूप से शैली और अत्यधिक व्यक्तिपरक है।
tawmas

यदि आप दो विशेषताओं के संबंध में सेट को क्रमबद्ध करना चाहते हैं, तो यह कमांड है: वर्ग मेटा: ऑर्डरिंग = ['last_name', 'first_name']
Tms91

135

आप टेम्प्लेट फ़िल्टर डायस्कॉर्ट https://docs.djangoproject.com/en/dev/ref/templates/builtins/#std:templatefilter-dictsort का उपयोग कर सकते हैं

यह काम करना चाहिए:

{% for event in eventsCollection %}
   {{ event.location }}
   {% for attendee in event.attendee_set.all|dictsort:"last_name" %}
     {{ attendee.first_name }} {{ attendee.last_name }}
   {% endfor %}
 {% endfor %}

22
महान ! और आश्चर्य करने वालों के लिए भी है dictsortreversed: docs.djangoproject.com/en/dev/ref/templates/builtins/…
मिकाएल

1
मेरे मूल पोस्ट से उद्धृत करने के लिए: आह, अगर केवल एक क्वेरी सेट एक डिक्शनरी थे तो डिस्कोर्ट काम करेंगे, लेकिन यह नहीं है और यह नहीं करता है।
डेल विल्सन

मुझे लगता है कि यह अभ्यास में कम होना चाहिए, और रिकॉर्ड लाने से पहले मॉडल को छँटाई करने दें।
acpmasquerade

1
@DaleWilson, मैं वास्तव में dictsortठीक तुम्हारी तरह कोड पर ठीक से काम कर रहा है । दिलचस्प बात यह है कि यह क्वेरी पर ठीक काम करता है।
mlissner

2
और बस आगे स्पष्टता के लिए, रिक्त स्थान मायने रखता है: {% for attendee in event.attendee_set.all|dictsort:"last_name" %}उपस्थित लोगों को छांटता है, लेकिन {% for attendee in event.attendee_set.all | dictsort:"last_name" %}लूप के उत्पादन को क्रमबद्ध करने का प्रयास करता है और टूट जाता है for
mattsl

3

एक समाधान के लिए एक कस्टम templatag बनाना है:

@register.filter
def order_by(queryset, args):
    args = [x.strip() for x in args.split(',')]
    return queryset.order_by(*args)

इस तरह का उपयोग करें:

{% for image in instance.folder.files|order_by:"original_filename" %}
   ...
{% endfor %}

0

regroup आप जो चाहते हैं वह करने में सक्षम होना चाहिए, लेकिन क्या कोई कारण है कि आप उन्हें उस तरह से आदेश नहीं दे सकते जैसे आप दृश्य में वापस चाहते हैं?


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

मैंने रीग्रुप को देखा और यह वह नहीं कर पाया जो मैं चाहता था। विशेष रूप से प्रलेखन कहता है: [उद्धरण] ध्यान दें कि {% regroup%} इसके इनपुट का आदेश नहीं देता है! हमारा उदाहरण इस तथ्य पर निर्भर करता है कि लोगों की सूची को पहले स्थान पर लिंग द्वारा आदेश दिया गया था। [endquote]
डेल विल्सन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.