2013-03-25 5 views
1

장고를 사용하여 메시징 응용 프로그램을 작성하려고합니다. postman을 사용하지 않는 이유는 사용자가 아닌 다른 개체간에 메시징이 필요하며 대부분 우편 배달부 기능이 필요하지 않기 때문입니다. 여기 관련 개체에 따른 개체 찾기

내 모델입니다 :

class Recipient(models.Model): 
    ... 
    def get_unread_threads(): 
     see below... 


class Thread(models.Model): 
    author = models.ForeignKey(Recipient, related_name='initiated_threads') 
    recipients = models.ManyToManyField(
     Tribe, 
     related_name='received_thread', 
     through='ThreadReading') 
    subject = models.CharField(max_length=64) 

    class Meta: 
     app_label = 'game' 


class Message(models.Model): 
    author = models.ForeignKey(Recipient, related_name='sent_messages') 
    date_add = models.DateTimeField(auto_now_add=True) 
    date_edit = models.DateTimeField(blank=True) 
    content = models.TextField(max_length=65535) 
    thread = models.ForeignKey(Thread) 

    class Meta: 
     get_latest_by = 'date' 


class ThreadReading(models.Model): 
    thread = models.ForeignKey(Thread) 
    recipient = models.ForeignKey(Recipient) 
    date_last_reading = models.DateTimeField(auto_now=True) 

내 문제에 대한 get_unread_threads입니다. 나는 그걸하는 법을 정말로 알 수 없다. 첫 시도입니다 :

def get_unread_threads(self): 
    """ 
    return a queryset corresponding to the threads 
    which at least one message is unread by the recipient 
    """ 
    try: 
     query = self.received_thread.filter(
       message__latest__date_add__gt=\ 
         self.threadreading_set.get(thread_id=F('id')).date_last_reading) 
    except ObjectDoesNotExist: 
     query = None 
    return query 

그러나 조회가 방법 latest을 따라갈 수 없기 때문에 분명히 작동하지 않습니다. 여기

+0

필자는 피할 수있는 정보 중복을 추가 할 수는 있습니다. – Vincent

답변

2

당신은 이동 :

# Get all the readings of the user 
thread_readings = recipient.threadreading_set.all() 

# Build a query object including all messages who's last reading is after the 
# last edit that was made AND whose thread is the thread of the current 
# iteration's thread reading 
q = models.Q() 
for thread_reading in thread_readings: 
    q = q | models.Q(
     models.Q(
      date_edit__lte=thread_reading.date_last_reading 
      & models.Q(
       thread=thread_reading.thread 
      ) 
     ) 
    ) 

# Get a queryset of all the messages, including the threads (via a JOIN) 
queryset = Message.objects.select_related('thread') 

# Now, exclude from the queryset every message that matches the above query 
# (edited prior to last reading) OR that is in the list of last readings 
queryset = queryset.exclude(
    q | models.Q(
     thread__pk__in=[thread_reading.pk for thread_reading in thread_readings] 
    ) 
) 

# Make an iterator (to pretend that this is efficient) and return a generator of it 
iterator = queryset.iterator() 
return (message.thread for message in iterator) 

:

자, 지금까지 실제로 이렇게하지 - 모델을 다시 생각. 나는 "객체 지향 분석 및 응용 프로그램 설계"라는 책을 읽을 것입니다. 그것은 당신이 데이터 모델링을 할 때 어떻게 생각하는지에 관해 많은 것을 가르쳐 줄 것입니다.

+0

그래, 그렇게 효율적으로 보이지 않는다 :) 어쨌든 queryset 제안과 책에 대한 감사. – Vincent

+0

@ Vincent - you 're welcome – orokusaki