2016-07-26 3 views
5

2 साधारण मॉडल हैं:Django के NotImplementedError: व्याख्या() + विशिष्ट (क्षेत्र) लागू नहीं है

class Question(TimeStampedModel): 
    text = models.CharField(max_length=40) 

class Answer(TimeStampedModel): 
    question = models.ForeignKey(Question, related_name='answers') 
    is_agreed = models.BooleanField() 
    author = models.ForeingKey(User, related_name='answers') 

और अब, मैं मेरी समस्या का वर्णन करेंगे।

In [18]: Question.objects.count() 
Out[18]: 3 

मैं 'is_user_agreed' और 'answers_amount' फ़ील्ड के साथ क्वेरीसमूह टिप्पणी करने की जरूरत है:

In [18]: user = User.objects.first() 
In [19]: qs = Question.objects.annotate(
    ...:    is_user_agreed=Case(
    ...:     When(answers__in=user.answers.filter(is_agreed=True), then=Value(True)), 
    ...:     When(answers__in=user.answers.filter(is_agreed=False), then=Value(False)), 
    ...:     default=Value(None), 
    ...:     output_field=NullBooleanField(), 
    ...:   ), 
    ...:  ).annotate(answers_amount=Count('answers')) 
    ...: qs.count() 
Out[19]: 4 

^यहाँ गिनती 4 है, लेकिन मैं db :( तो में केवल 3 प्रश्न हैं, मैं distinct()

In [20]: qs.distinct().count() 
Out[20]: 4 # but distinct doesn't work 

In [21]: qs.distinct('id').count() 

साथ की कोशिश की है और कोड की अंतिम पंक्ति के बाद मैं इस अपवाद मिल गया है:

NotImplementedError: annotate() + distinct(fields) is not implemented. 

मैं भी इस चाल annotate(Count('id')).filter(id__count__gt=1)

लेकिन इस मामले में मैं सभी डुप्लिकेट पंक्तियों को खो रहा हूँ, और qs.count() 2.

अद्यतन है उपयोग करने के लिए कोशिश की है: समस्या क्वेरीसेट में डुप्लिकेट पंक्तियां है।

समाधान: (व्लादिमीर का दूसरा दृष्टिकोण के विस्तारित संस्करण)

user = User.objects.first() 
user_agreed_questions = user.answers.filter(
    is_agreed=True).values_list('question_id', flat=True).distinct() 

user_not_agreed_questions = user.answers.filter(
    is_agreed=False).values_list('question_id', flat=True).distinct() 

Question.objects.annotate(
    answer_amount=Count('answers'), 
     is_user_agreed=Case(
      When(id__in=user_agreed_questions, then=True), 
      When(id__in=user_not_agreed_questions, then=False), 
      default=None, 
     output_field=NullBooleanField(), 
    ), 
) 
+0

मुझे पूरा यकीन नहीं है कि आप क्या करने की कोशिश कर रहे हैं, लेकिन [यह प्रश्न मदद कर सकता है] (http://stackoverflow.com/questions/13145254/django-annotate-count-with-a-distinct-field)। – solarissmoke

+0

क्या आप पोस्टग्रेस का उपयोग कर रहे हैं? – Sayse

+0

संक्षेप में, आप प्रश्न और उत्तर तालिका में शामिल हो जाते हैं। तो यदि पहले प्रश्न में दो जवाब हैं, तो दूसरे प्रश्न का एक जवाब है, तीसरे प्रश्न में एक ऑनवर है, आपको 4 (2 + 1 + 1) मिलेगा। क्या आप वर्णन कर सकते हैं कि क्वेरीसेट का वांछित परिणाम क्या है? आप क्या प्राप्त करना चाहते हैं? –

उत्तर

4

इस प्रयास करें:

Question.objects.annotate(
    answer_amount=Count('answers'), 
    is_user_agreed=F('answers__is_agreed'), 
).order_by('id', '-answers__is_agreed').distinct('id') 

तो question कोई answers है, तो question.is_user_agreedNone है। यदि question में कम से कम एक answeranswer.is_agreed=True है, तो question.is_agreedTrue है। अन्यथा, is_user_agreedFalse है।

या इस:

agreed_questons = Answer.objects.filter(
    is_agreed=True, 
).values_list('question_id', flat=True).distinct() 

Question.objects.annotate(
    answer_amount=Count('answers'), 
    is_agreed=Case(
     When(id__in=agreed_questions, then=True), 
     When(answers__isnull=True, then=None), 
     default=False, 
     output_field=NullBooleanField(), 
    ), 
) 

agreed_questonsquestions की id की सूची, कि answer.is_agreed=True साथ कम से कम एक answer है।

+1

मेरी एनोटेट अच्छी तरह से काम करती है, मुख्य समस्या परिणाम quesryset में डुप्लिकेट प्रविष्टियां है। –

+0

मैंने आपके दूसरे दृष्टिकोण की जांच की है और यह मेरे लिए काम करता है (प्रश्न में विवरण)। बहुत धन्यवाद! –

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