मैं Django में काम कर रहा हूँ और मेरी व्यवस्थापक साइट में कुछ ठीक से प्रदर्शित करने में समस्या आ रही है। ये हैं मॉडल

class IndexSetSize(models.Model):
    """ A time series of sizes for each index set """
    index_set = models.ForeignKey(IndexSet, on_delete=models.CASCADE)
    byte_size = models.BigIntegerField()
    timestamp = models.DateTimeField()

class IndexSet(models.Model):
    title = models.CharField(max_length=4096)
    # ...  some other stuff that isn't really important
    def __str__(self):
        return f"{self.title}"

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

वर्तमान व्यवस्थापक मॉडल इस तरह दिखता है:

class IndexSetSizeAdmin(admin.ModelAdmin):
    """ View-only admin for index set sizes """
    fields = ["index_set", "total_size", "byte_size", "timestamp"]
    list_display = ["index_set", "total_size", "timestamp"]
    search_fields = ["index_set"]
    list_filter = ["index_set__title"]

    def total_size(self, obj):
        """ Returns human readable size """
        if obj.total_size:
            return humanize.naturalsize(obj.total_size)
        return "-"
    total_size.admin_order_field = 'total_size'

    def get_queryset(self, request):
        queryset = super().get_queryset(request).select_related()
        queryset = queryset.annotate(
            total_size=Sum('byte_size', filter=Q(index_set__in_graylog=True)))
        return queryset

ऐसा लगता है कि Django में समूह करने का उचित तरीका .values() का उपयोग करना है, हालांकि अगर मैं get_queryset में इसका उपयोग करता हूं, तो Cannot call select_related() after .values() or .values_list() कहकर एक त्रुटि फेंक दी जाती है। मुझे दस्तावेज़ों में खोजने में परेशानी हो रही है यदि मूल्यों/एनोटेट/कुल के लिए 'सही' तरीका है जो get_queryset के साथ सही ढंग से काम करेगा। यह क्वेरी द्वारा एक बहुत ही सरल योग/समूह है जिसे मैं करने की कोशिश कर रहा हूं, लेकिन मुझे यकीन नहीं है कि इसे पूरा करने के लिए "Django तरीका" क्या है।

धन्यवाद

0
graeme 2 अक्टूबर 2019, 15:03

1 उत्तर

सबसे बढ़िया उत्तर

मुझे नहीं लगता कि आप index_set द्वारा get_queryset में पूर्ण क्वेरीसेट और समूह को वापस करने में सक्षम होंगे क्योंकि आप sql में एक व्यक्तिगत कॉलम द्वारा सभी कॉलम लेकिन समूह का चयन नहीं कर सकते हैं

SELECT *, SUM(index_size) FROM indexsetsize GROUP BY index_set   // doesn't work

आप समग्र मूल्य प्राप्त करने के लिए total_size विधि में एक अतिरिक्त क्वेरी कर सकते हैं। हालांकि, यह लौटाई गई प्रत्येक पंक्ति के लिए क्वेरी निष्पादित करेगा और आपके पृष्ठ लोड को धीमा कर देगा।

    def total_size(self, obj):
        """ Returns human readable size """
        return humanize.naturalsize(sum(IndexSetSize.objects.filter(
                                        index_set=obj.index_set).values_list(
                                       'byte_size', flat=True)))
    total_size.admin_order_field = 'total_size'

इस एनोटेशन को IndexSetAdmin के भीतर करना बेहतर होगा क्योंकि index_set को पहले से ही रिवर्स फॉरेन की के माध्यम से समूहीकृत किया जाएगा। इसका मतलब यह होगा कि आप एनोटेशन को get_queryset में कर सकते हैं। मैं related_name को विदेशी कुंजी पर IndexSetSize पर भी सेट करूंगा ताकि आप उस नाम का उपयोग करके IndexSet से वास्तविक IndexSetSize वस्तुओं तक पहुंच सकें।

class IndexSetSize(models.Model):
    index_set = models.ForeignKey(IndexSet, on_delete=models.CASCADE, related_name='index_set_sizes')
    ...

class IndexSetAdmin(admin.ModelAdmin):
    ...

    def total_size(self, obj):
        """ Returns human readable size """
        if obj.total_size:
            return humanize.naturalsize(obj.total_size)
        return "-"

    def get_queryset(self, request):
        queryset = super().get_queryset(request).prefetch_related('index_set_sizes').annotate(
            total_size=Sum('index_set_sizes__byte_size')).order_by('total_size')
        return queryset
0
Mikey Lockwood 4 अक्टूबर 2019, 14:27