Reputation: 593
I'm trying to create a twitter clone and this is my user and tweet Model(some irrelevant fields have been removed).
class TwitterUser(models.Model):
user = models.OneToOneField(to=User, on_delete=models.CASCADE,primary_key=True)
Bio = models.CharField(max_length=200, blank=True)
Location = models.CharField(max_length=200, blank=True)
Website = models.URLField(blank=True)
ProfilePicture = models.ImageField(upload_to="Twitter", default="../static/twitter/images/default_profile.png")
CreateDate = models.DateField(default=timezone.now)
class Tweet(models.Model):
TweetBody = models.CharField(max_length=140, blank=False)
TweetDate = models.DateTimeField(default=timezone.now)
Owner= models.ForeignKey(to=TwitterUser,on_delete=models.CASCADE,related_name="Owner")
RetweetedBy= models.ManyToManyField(to=TwitterUser,related_name="Retweeted",blank=True,through="RetweetIntermediate")
and this the table that my many to many relationship for retweet is using.
class RetweetIntermediate(models.Model):
twitteruser=models.ForeignKey(TwitterUser,on_delete=models.CASCADE)
tweet=models.ForeignKey(Tweet,on_delete=models.CASCADE)
retweetDate=models.DateTimeField(default=timezone.now)
In profile view all the tweets and retweets should be shown ordered by date what I'm doing right now (and it is working fine) is this:
def keymaker(a):
return a.TweetDate
def ProfileView(request):
tweets= list(Tweet.objects.filter(Owner=user.user_id,IsReplyToTweet__isnull=True).order_by("-TweetDate"))
retweets = list(user.Retweeted.all().order_by("-id"))
retweetInter=RetweetIntermediate.objects.all().order_by("-tweet_id")
for i , j in zip(retweets,retweetInter):
i.TweetDate=j.retweetDate
tweets=(tweets+retweets)
tweets.sort(key=keymaker,reverse=True)
I retrieve all the tweets ordered by date. then I retrieve all of retweets and make a list out of them and change the data of tweet to the date saved in intermediate table and merge both lists and sort them by date. I want to know is there a better way or more standard way to do this?
Thanks in advance.
Upvotes: 0
Views: 99
Reputation: 2861
You can do it using union together with annotate.
from django.db.models import F
tweets_qs = Tweet.objects\
.filter(Owner=user, IsReplyToTweet__isnull=True)\
.annotate(date=F('TweetDate'))
retweets_qs = Tweet.objects\
.filter(retweetintermediate__twitteruser=user)\
.annotate(date=F('retweetintermediate__retweetDate'))
timeline_qs = tweets_qs.union(retweets_qs).order_by('-date')
Notice that both querysets have Tweet
objects.
Edit: Sorry for not understanding the question correctly the first time.
Upvotes: 1