Search code examples
djangopython-3.xtwittertweepy

How to build a django model to store twitter conversations?


I'm building a tool, that gets user timeline tweets and their responses and I need to find out how to store those conversations in a database to render them afterwards in a template.

To get a conversation, I use a while loop, that gets 'in_reply_to_status_id' of a tweet, then retrieves the status object of this reply by the id, finds its 'in_reply_to_status_id' etc till the whole conversation gets retrieved.

This is the code I use:

conversation = []

while True:

    response = api.get_status(id=tweet_id, tweet_mode='extended')._json

    if response['in_reply_to_status_id'] == None:
        break
    else:
        message_dict = {}
        message_dict['author'] = response['user']['screen_name']
        message_dict['text'] = response['full_text']
        message_dict['created_at'] = response['created_at']
        message_dict['author_profile_url'] = response['user']['profile_image_url']
        conversation.append(message_dict)
        tweet_id = response['in_reply_to_status_id']

if len(conversation) == 0:
    return None

return reversed(conversation)

In my models.py I have a Tweet model and I need to find out how to make a model that stores the whole conversation/dialogue/thread retrieved by the script above. Also, it should be possible to render the conversation as a simple chat dialogue afterward.

My first thought was to add "replies" field to my Tweet model and store the conversation as a JSON but this doesn't look like the right solution to me.


Solution

  • I don't know all the fields that you get or want to store, but for what I saw at your code this should work (set the max_length at what it should do, I don't know):

    Tweet(models.Model):
        author = models.Charfield(max_length=50)
        text = models.Charfield(max_length=500)
        author_profile_url = models.URLField(null=True, blank=True)
        reply_to = models.ForeignKey(Tweet, on_delete=models.CASCADE, related_name='replies')
        creation_date = models.DateTimeField()
    

    To print all the conversation you will need to iterate the FK looking for all the related objects and order them by creation_date.

    If what you want is to show only one conversation you should send through the view the initial object of the conversation and then you could do something like:

    {{ tweet.author }}
    {{ tweet.text }}
    {{ tweet.creation_date }}
    {% if tweet.reply_to_set.count > 0 %}
        {% with replies=tweet.reply_to_set.all %}
            {% for reply in replies %}
                {{ reply.author }}
                {{ reply.text }}
                {{ reply.creation_date }}
                replies to this message: {{ reply.reply_to_set.count }}
            {% endfor %}
        {% endwith %}
    {% endif %}
    

    This will show first the tweet information, then check if there are replies and if there are show you the information of each one. Inside that reply I added the replies to this message in which you can let the people know if that reply have other replies. Just in case you want to do infinite reply system (like twitter). But then there you could add a link to this same template in which the object is that reply, so that will be the main tweet and then the replies will be shown.