I am trying to send the text of tweets (from tweepy) to a template in django 2.0 so I can display it in the browser. But every time I try to see if the browser has the tweets it acts as if there was nothing in the object I sent from the view.
I suspect the response from tweepy is in a different format from the expected in django generic views, but I don't know how to solve it if it's indeed that.
For context, you send a username from a simple form before the program searches for tweets for that username and collects them from the API (no errors here, I checked it through the manage.py shell and all the tweets are there in the model). Then, it sends that object to the template tweet_detail.html so it may appear.
I've just started learning Django, but the docs at https://docs.djangoproject.com/en/2.0/intro/tutorial04/ don't have the answer.
Here's my URLs
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('tweet/search', views.search, name='search'),
path('tweet/detail', views.TweetDetailView.as_view(), name='detail'),
path('tweet/collect', views.collect_tweets, name='collect_tweets'),
]
My Models
from django.db import models
class Tweet(models.Model):
tweet_text = models.CharField(max_length=180)
def __str__(self):
return self.tweet_text
My Views
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic
import tweepy
from .models import Tweet
def collect_tweets(request):
try:
CONSUMER_KEY = 'xxx'
CONSUMER_SECRET = 'xxx'
ACCESS_TOKEN = 'xxx'
ACCESS_SECRET = 'xxx'
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_SECRET)
api = tweepy.API(auth)
tweets = api.user_timeline(screen_name=request.POST.get('user_name'), count=5, tweet_mode="extended")
for tweet in tweets [:5]:
t = Tweet(tweet_text=tweet.full_text)
t.save()
return render(request, 'polls/tweet_detail.html')
except KeyError:
return render(request, 'polls/tweet_detail.html')
def search(request):
return render(request, 'polls/tweet.html')
class TweetDetailView(generic.ListView):
template_name= 'polls/tweet_detail.html'
context_object_name= 'tweets'
def get_queryset(self):
return Tweet.objects.all()
The template to send the username for collection (tweet.html)
<form action="{% url 'polls:collect_tweets' %}" method="post">
{% csrf_token %}
<label for="1">Username: </label><br />
<input name="user_name" id="1"/>
<input type="submit" value="Submit" />
</form>
And the template for showing the results (tweet_detail.html)
{% if tweets %}
<ul>
{% for tweet in tweets %}
<li> {{ tweet }} </li>
{% endfor %}
</ul>
{% else %}
<p>No tweets</p> <!--It always displays this-->
{% endif %}
I know there are probably a lot of broken rules for coding in django here, but the main concern is the result:
No tweets
But when I check the manage.py shell:
>>> from polls.models import Tweet
>>> Tweet.objects.all()
<QuerySet [<Tweet: There is the correct text here>, <Tweet: And also here>]>
Could someone help?
UPDATE: if I change the search at the view from...
tweets = api.user_timeline(screen_name=request.POST.get('user_name'), count=5, tweet_mode="extended")
to...
tweets = tweepy.Cursor(api.search, q=request.POST.get('user_name'), count=100).items(5)
It works, but using the user_timeline is preferable to my situation than Cursor