2014-09-23 3 views
0

У меня есть эти Models, и я хочу, чтобы иметь возможность выбирать из первых двух.Как выбрать из двух разных таблиц в Django?

class Comments(models.Model): 
    post_id = models.ForeignKey('Posts') 
    content = models.CharField(max_length=480) 
    time_created = models.DateTimeField() 

class Posts(models.Model): 
    user_id = models.ForeignKey('Users') 
    content = models.CharField(max_length=480) 
    time_created = models.DateTimeField() 

class Users(models.Model): 
    email = models.EmailField() 
    name = models.CharField(max_length=60) 
    time_created = models.DateTimeField() 

Я хочу, чтобы иметь возможность выбрать сообщения и их комментарии и они отсортированы по datetime так, что Posts и Comments будут смешиваться при отображении их. Я думаю, что Twitter делает то же самое с их Tweets и Retweets.

+1

Возможно, вы захотите изучить [отношения многие-ко-многим] (https://docs.djangoproject.com/en/1.7/topics/db/examples/many_to_many/). – Celeo

+0

@Celeo: Я не понимаю, как отношения «многие-ко-многим» здесь будут достаточно, поскольку «Почта» не может быть выполнена многими «Пользователями», а также «Комментарий» относится ко многим сообщениям. Можете ли вы проливать больше света? – Yax

+0

Я должен был связать [много-к-одному] (https://docs.djangoproject.com/en/1.7/ref/models/fields/#foreignkey). – Celeo

ответ

1

Возможно, вы не сможете сделать это с помощью одного запроса. Однако вы можете получить два запроса и использовать itertools для объединения двух итераций.

Пример, если вы хотите, сообщения и комментарии пользователей,

posts = user.posts_set.all() #or Posts.objects.filter(user=user) 
comments = Comments.objects.filter(post_id__user=user) 

import itertools 
qs = itertools.chain.from_iterable([posts, comments]) 

В качестве альтернативы, если вы не нарезая QuerySet,

qs = posts | comments 

Теперь вы можете заказать по ключевым:

qs_sorted = sorted(qs, key=lambda x: x.time_created) 

Возможно, вы захотите ограничить набор запросов, чтобы избежать необычного времени загрузки, поскольку наборы запросов являются eva luated int he sorted function

+0

Спасибо, но как узнать, какой комментарий для какого сообщения? Я не вижу отношения в запросе. – Yax

+1

Вы можете использовать 'hasattr (obj, post_id)', чтобы увидеть, является ли это комментарием или нет. Это был пример, но вы можете использовать любой уникальный атрибут для проверки типа. – karthikr

0

Чтобы выбрать определенную группу сообщений:

filtered_posts = Posts.objects.filter(however_you_filter_your_queryset) 

Чтобы получить все комментарии, связанные с определенным постом:

related_comments = p.comments_set.all() 

Вы можете создать список кортежей, где каждый держит (data_type, content, time):

tuple_list = [] 
for p in filtered_posts: 
    post_tuple = ('post', p.content, p.time_created) 
    tuple_list.append(post_tuple) 
    related_comments = p.comments_set.all() 
    for c in related_comments: 
     comment_tuple = ('comment', p.content, p.time_created) 
     tuple_list.append(comment_tuple) 

Вы в конечном итоге получаете список кортежей, содержащих все t он публикует ваши комментарии, связанные с этими сообщениями. Если вы отсортируете свой список по третьему элементу кортежей, вы будете сортировать по полю datetime. Вы также можете удалить дубликаты, сделав set().

Смежные вопросы