from django.db import models
from django.contrib.auth.models import User
import datetime
class Account(models.Model):
"""
I'm using doctests, because they keep everything in one file.
If I make a lot of tests, I'd break it out into a separate file.
But this is a one file coding sample, so I wont do that.
Account is simply the twitter specific bits to add on to the
regular Django User class. manages a set of tweets, keeps
track of following, etc.
First thing we need is a couple Django Users to add our
Account objects to.
>>> user1 = User(username="user1")
>>> user1.save()
>>> user2 = User(username="user2")
>>> user2.save()
Then we make some accounts, also pretty boring.
>>> account1 = Account(user=user1)
>>> account1.save()
>>> account2 = Account(user=user2)
>>> account2.save()
Make some tweets to play around with...
>>> account1.new_tweet("Twiddle twiddle tweet tweet.")
>>> account1.new_tweet("Inconsequential twaddle.")
Make sure the tweets got made.
>>> tweets = Tweet.objects.all()
>>> tweets[0].owner.user.username
u'user1'
Get a list of the user's current tweets.
>>> len(account1.get_latesttweets())
2
Make sure account2 doesn't get account1's tweets...
>>> account2.get_latesttweets()
[]
Make sure an account can see the tweets from
the accounts it's following
>>> account2.get_followingtweets()
[]
>>> account2.add_follower(account1)
>>> account2.get_followingtweets()
[<Tweet: Tweet object>, <Tweet: Tweet object>]
Also ensure that following is not necessarily
reciprocal
>>> account1.get_followingtweets()
[]
"""
def __unicode__(self):
return self.user.username
user = models.ForeignKey(User, unique=True)
# manytomany, so following isn't reciprocal
following = models.ManyToManyField('self', null=True )
def new_tweet(self, tweet):
tweet = Tweet(owner=self,
message=tweet,
time_stamp=datetime.datetime.now())
tweet.save()
def get_latesttweets(self):
# performance -- values() is much faster than building an object...
# and this would probably just be used to display a list of tweets,
# you'd want to generate objects if you want to do manipulation.
# (Oh how I've learned this lesson)
return self.tweets.all().values()
def add_follower(self, follower):
self.following.add(follower) # may be backwards? need to test
def get_followingtweets(self):
return Tweet.objects.filter(owner__in=self.following.all())[:20]
def get_favorites(self):
return self.favorites.all()
class Tweet(models.Model):
"""
>>> account1 = Account.objects.get(user__username='user1')
>>> account2 = Account.objects.get(user__username='user2')
Get some tweets to play with...
>>> tweets = Tweet.objects.filter(owner=account1)
>>> len(tweets)
2
Test that the ordering is correct, from the Meta class...
tweet[0].time_stamp < tweet[1].timestamp
1
Add a tweet to account2's favorites
>>> tweets[0].favorite_of(account2)
And make sure it gets stored...
>>> account2.get_favorites()
[<Tweet: Tweet object>]
"""
owner = models.ForeignKey('Account',
related_name='tweets')
message = models.CharField(max_length=140)
# I don't know why I originally made this one a ForeignKey,
# but ManyToMany is the right choice here...
favoriteof = models.ManyToManyField('Account',
null=True,
related_name='favorites')
mentions = models.ForeignKey('self',
null=True)
time_stamp = models.DateTimeField() # auto_now_add is deprecated...
class Meta:
ordering = ('-time_stamp',)
def favorite_of(self, account):
self.favoriteof.add(account)