As was the case with bottles, I think that if you start by creating a Twitter client, you will deepen your basic understanding of Django. By the way, I will make something that allows you to see posts, replies, and home timelines on one screen.
The result is an image like this.
It will be a specification such as.
If you want to try it under similar conditions, please refer to the previous article. http://qiita.com/Gen6/items/735245423b65698428be
.py
myapp/views.py
from requests_oauthlib import OAuth1Session
import time, calendar
import datetime
import json
import re
import os
import requests
import sys, codecs
sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
from django.http.response import HttpResponse
from django.shortcuts import render
def index(request):
msg = request.GET.get('words')
C_KEY = '********************'
C_SECRET = '********************'
A_KEY = '********************'
A_SECRET = '********************'
url = 'https://api.twitter.com/1.1/statuses/update.json'
params = {'status': msg,'lang': 'ja'}
tw = OAuth1Session(C_KEY,C_SECRET,A_KEY,A_SECRET)
req = tw.post(url, params = params)
url = 'https://api.twitter.com/1.1/statuses/home_timeline.json'
params = {'count': 1}
req = tw.get(url, params = params)
if req.status_code == 200:
timeline = json.loads(req.text)
limit = req.headers['x-rate-limit-remaining']
for tweet in timeline:
Text = (tweet['text'])
User = (tweet['user']['screen_name'])
Name = (tweet['user']['name'])
Img = (tweet['user']['profile_image_url'])
Created_at = YmdHMS(tweet['created_at'])
Message = {
'Words': msg,
'timeline': timeline,
'API_limit': limit,
'Text': Text,
'User': User,
'Name': Name,
'Img': Img,
'Created_at': Created_at,
}
return render(request, 'index.html', Message)
else:
Error = {
'Error_message': 'API restricted',
}
return render(request, 'index.html', Error)
def YmdHMS(created_at):
time_utc = time.strptime(created_at, '%a %b %d %H:%M:%S +0000 %Y')
unix_time = calendar.timegm(time_utc)
time_local = time.localtime(unix_time)
return int(time.strftime('%Y%m%d%H%M%S', time_local))
YdmHMS.py
def YmdHMS(created_at):
time_utc = time.strptime(created_at, '%a %b %d %H:%M:%S +0000 %Y')
unix_time = calendar.timegm(time_utc)
time_local = time.localtime(unix_time)
return str(time.strftime('%Y'+'Year'+'%m'+'Month'+'%d'+'Day'+'%H'+'Time'+'%M'+'Minutes', time_local))
templates/base.html
<!DOCTYPE html>
<html lang="la">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="../static/css/bootstrap.min.css" rel="stylesheet">
<link href="../static/css/custom.css" rel="stylesheet">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="../static/js/bootstrap.min.js"></script>
<title></title>
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
The URL is solid, isn't it?
templates/index.html
{% extends "base.html" %}
{% block body %}
<div class="container">
<div class="row">
<div class="col-md-6">
<form action="" method="get" class="form-group">
<label><input type="text" size="60" name="words" class="form-control" placeholder="Tweet"></label>
<input type="submit" class="btn btn-primary" value="Send">
<input type="button" class="btn btn-warning" value="Reload" onclick="location.reload();" />
</form>
{% if Words %}
<p>「{{ Words }}I tweeted.</p>
{% endif %}
<p class="error-message">{{ Error_message }}</p>
<p><span class="status">API-Limit:{{ API_limit }}</p>
</div>
<script type="text/javascript">
$(function() {
$(".reply").click(function() {
var newText = '@{{ User }} ';
$(':text[name="words"]').val(newText);
});
});
</script>
<div class="col-md-6">
{% if API_limit %}
<dl>
<dt><span class="reply"><img class="users-img" src="{{ Img }}">{{ User }}/{{ Name }}</span><span class="d-time">{{ Created_at }}</span></dt>
<dd>{{ Text }}</dd>
</dl>
<ul id="output"></ul>
{% endif %}
</div>
</div>
</div>
{% endblock %}
static/css/custom.css
.container {
width: 100%;
}
.row {
margin: 40px auto;
}
.status {
background: #E2264D;
border-radius: 4px;
color: #fff;
padding: 4px;
width: 100px;
text-align: center;
margin-right: 10px;
}
.reply {
cursor: pointer;
font-weight: bold;
}
.btn-primary {
margin-right: 2px;
}
.d-time {
margin-left: 10px;
border: 1px solid #d8d8d8;
border-radius: 4px;
padding: 4px;
font-weight: normal;
}
ul li {
list-style: none;
}
.users-img {
margin-right: 10px;
border-radius: 4px;
}
dt {
margin-bottom: 10px;
}
.error-message {
color: #ff3300;
}
If you want to save it in the database, please see the following article. http://qiita.com/Gen6/items/907d869cdf1d588a4751
Create with an image like the one above.
I will write about line 107.
mysite/settings.py
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
It is a pattern that implements posting, mention, and search. Since it is written in one views file, it is not easy to maintain, but please refer to it.
You can put the KEY outside or write it more simply, but it is easy to understand. Try different things to keep your code clean.
The search result will be a pattern saved in the database.
myapp/views.py
from requests_oauthlib import OAuth1Session
import time, calendar
import datetime
import json
import re
import os
import requests
import sys, codecs
sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
from django.http.response import HttpResponse
from django.shortcuts import render
from myapp.models import Supermodel
def index(request):
msg = request.GET.get('words')
C_KEY = '********************'
C_SECRET = '********************'
A_KEY = '********************'
A_SECRET = '********************'
url = 'https://api.twitter.com/1.1/statuses/update.json'
params = {'status': msg,'lang': 'ja'}
tw = OAuth1Session(C_KEY,C_SECRET,A_KEY,A_SECRET)
req = tw.post(url, params = params)
url = 'https://api.twitter.com/1.1/statuses/home_timeline.json'
params = {'count': 1}
req = tw.get(url, params = params)
if req.status_code == 200:
timeline = json.loads(req.text)
limit = req.headers['x-rate-limit-remaining']
for tweet in timeline:
Text = (tweet['text'])
User = (tweet['user']['screen_name'])
Name = (tweet['user']['name'])
Img = (tweet['user']['profile_image_url'])
Created_at = YmdHMS(tweet['created_at'])
Message = {
'Words': msg,
'timeline': timeline,
'API_limit': limit,
'Text': Text,
'User': User,
'Name': Name,
'Img': Img,
'Created_at': Created_at,
}
return render(request, 'index.html', Message)
else:
Error = {
'Error_message': 'API restricted',
}
return render(request, 'index.html', Error)
def search(request):
search_words = 'hogehoge'
search_words = request.GET.get('words')
C_KEY = '********************'
C_SECRET = '********************'
A_KEY = '********************'
A_SECRET = '********************'
tw = OAuth1Session(C_KEY,C_SECRET,A_KEY,A_SECRET)
url = 'https://api.twitter.com/1.1/search/tweets.json?'
params = {
'q': (search_words, 'utf-8'),
'lang': 'ja',
'count': '1'
}
req = tw.get(url, params = params)
if req.status_code == 200:
timeline = json.loads(req.text)
limit = req.headers['x-rate-limit-remaining']
for tweet in timeline['statuses']:
Text = (tweet['text'])
User = (tweet['user']['screen_name'])
Name = (tweet['user']['name'])
Img = (tweet['user']['profile_image_url'])
Created_at = YmdHMS(tweet['created_at'])
data = Supermodel()
data.user_id = User
data.user_name = Name
data.user_img = Img
data.user_text = Text
data.user_created_at = Created_at
data.save()
Message = {
'Words': search_words,
'timeline': timeline,
'API_limit': limit,
'Text': Text,
'User': User,
'Name': Name,
'Img': Img,
'Created_at': Created_at,
}
return render(request, 'search.html', Message)
else:
Error = {
'Error_message': 'API restricted',
}
return render(request, 'search.html', Error)
def mentions(request):
msg = request.GET.get('words')
C_KEY = '********************'
C_SECRET = '********************'
A_KEY = '********************'
A_SECRET = '********************'
url = 'https://api.twitter.com/1.1/statuses/update.json'
params = {'status': msg,'lang': 'ja'}
tw = OAuth1Session(C_KEY,C_SECRET,A_KEY,A_SECRET)
req = tw.post(url, params = params)
url = 'https://api.twitter.com/1.1/statuses/mentions_timeline.json'
params = {'count': 1}
req = tw.get(url, params = params)
if req.status_code == 200:
timeline = json.loads(req.text)
limit = req.headers['x-rate-limit-remaining']
for tweet in timeline:
Text = (tweet['text'])
User = (tweet['user']['screen_name'])
Name = (tweet['user']['name'])
Img = (tweet['user']['profile_image_url'])
Created_at = YmdHMS(tweet['created_at'])
Message = {
'Words': msg,
'timeline': timeline,
'API_limit': limit,
'Text': Text,
'User': User,
'Name': Name,
'Img': Img,
'Created_at': Created_at,
}
return render(request, 'mentions.html', Message)
else:
Error = {
'Error_message': 'API restricted',
}
return render(request, 'mentions.html', Error)
def YmdHMS(created_at):
time_utc = time.strptime(created_at, '%a %b %d %H:%M:%S +0000 %Y')
unix_time = calendar.timegm(time_utc)
time_local = time.localtime(unix_time)
return int(time.strftime('%Y%m%d%H%M%S', time_local))
The operation to save to the database is as follows. I think it's simple, easy to understand, and easy to understand what you're doing.
data = Supermodel()
data.user_id = User
data.user_name = Name
data.user_img = Img
data.user_text = Text
data.user_created_at = Created_at
data.save()
I'm using bootstrap.
templates/base.html
<!DOCTYPE html>
<html lang="la">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="../static/css/bootstrap.min.css" rel="stylesheet">
<link href="../static/css/custom.css" rel="stylesheet">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="../static/js/bootstrap.min.js"></script>
<title></title>
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
templates/index.html
{% extends "base.html" %}
{% block body %}
<div class="container">
<nav class="nav">
<ul>
<li><a href="{% url 'index' %}">POST</a></li>
<li><a href="{% url 'search' %}">SEARCH</a></li>
<li><a href="{% url 'mentions' %}">MENTIONS</a></li>
</ul>
</nav>
<div class="row">
<div class="col-md-6">
<form action="" method="get" class="form-group">
<label><input type="text" size="60" name="words" class="form-control" placeholder="Tweet"></label>
<input type="submit" class="btn btn-primary" value="Send">
<input type="button" class="btn btn-warning" value="Reload" onclick="location.reload();" />
</form>
{% if Words %}
<p>「{{ Words }}I tweeted.</p>
{% endif %}
<p class="error-message">{{ Error_message }}</p>
<p><span class="status">API-Limit:{{ API_limit }}</p>
</div>
<script type="text/javascript">
$(function() {
$(".reply").click(function() {
var newText = '@{{ User }} ';
$(':text[name="words"]').val(newText);
});
});
</script>
<div class="col-md-6">
{% if API_limit %}
<dl>
<dt><span class="reply"><img class="users-img" src="{{ Img }}">{{ User }}/{{ Name }}</span><span class="d-time">{{ Created_at }}</span></dt>
<dd>{{ Text }}</dd>
</dl>
{% endif %}
</div>
</div>
</div>
{% endblock %}
templates/search.html
{% extends "base.html" %}
{% block body %}
<div class="container">
<nav class="nav">
<ul>
<li><a href="{% url 'index' %}">POST</a></li>
<li><a href="{% url 'search' %}">SEARCH</a></li>
<li><a href="{% url 'mentions' %}">MENTIONS</a></li>
</ul>
</nav>
<div class="row">
<div class="col-md-6">
<form action="" method="get" class="form-group">
<label><input type="text" size="60" name="words" class="form-control" placeholder="Search"></label>
<input type="submit" class="btn btn-primary" value="Send">
<input type="button" class="btn btn-warning" value="Reload" onclick="location.reload();" />
</form>
{% if Words %}
<p>「{{ Words }}Was searched for.</p>
{% endif %}
<p class="error-message">{{ Error_message }}</p>
<p><span class="status">API-Limit:{{ API_limit }}</p>
</div>
<script type="text/javascript">
$(function() {
$(".reply").click(function() {
var newText = '@{{ User }} ';
$(':text[name="words"]').val(newText);
});
});
</script>
<div class="col-md-6">
{% if API_limit %}
<dl>
<dt><span class="reply"><img class="users-img" src="{{ Img }}">{{ User }}/{{ Name }}</span><span class="d-time">{{ Created_at }}</span></dt>
<dd>{{ Text }}</dd>
</dl>
{% endif %}
</div>
</div>
</div>
{% endblock %}
templates/mentions.html
{% extends "base.html" %}
{% block body %}
<div class="container">
<nav class="nav">
<ul>
<li><a href="{% url 'index' %}">POST</a></li>
<li><a href="{% url 'search' %}">SEARCH</a></li>
<li><a href="{% url 'mentions' %}">MENTIONS</a></li>
</ul>
</nav>
<div class="row">
<div class="col-md-6">
<form action="" method="get" class="form-group">
<label><input type="text" size="60" name="words" class="form-control" placeholder="Tweet"></label>
<input type="submit" class="btn btn-primary" value="Send">
<input type="button" class="btn btn-warning" value="Reload" onclick="location.reload();" />
</form>
{% if Words %}
<p>「{{ Words }}I tweeted.</p>
{% endif %}
<p class="error-message">{{ Error_message }}</p>
<p><span class="status">API-Limit:{{ API_limit }}</p>
</div>
<script type="text/javascript">
$(function() {
$(".reply").click(function() {
var newText = '@{{ User }} ';
$(':text[name="words"]').val(newText);
});
});
</script>
<div class="col-md-6">
{% if API_limit %}
<dl>
<dt><span class="reply"><img class="users-img" src="{{ Img }}">{{ User }}/{{ Name }}</span><span class="d-time">{{ Created_at }}</span></dt>
<dd>{{ Text }}</dd>
</dl>
{% endif %}
</div>
</div>
</div>
{% endblock %}
CSS
static/css/custom.css
.container {
width: 100%;
}
.nav {
background: rgba(0,0,0,0.7);
color: #fff;
width: 100%;
margin: 0 auto;
}
.nav ul li {
list-style: none;
margin: 10px auto;
}
.nav ul {
margin-left: -20px;
}
.nav li {
float: left;
margin-right: 10px!important;
}
.nav li a:link, .nav li a:visited {
color: #fff!important;
}
.row {
margin: 40px auto;
}
.status {
background: #E2264D;
border-radius: 4px;
color: #fff;
padding: 4px;
width: 100px;
text-align: center;
margin-right: 10px;
}
.reply {
cursor: pointer;
font-weight: bold;
}
.btn-primary {
margin-right: 2px;
}
.d-time {
margin-left: 10px;
border: 1px solid #d8d8d8;
border-radius: 4px;
padding: 4px;
font-weight: normal;
}
ul li {
list-style: none;
}
.users-img {
margin-right: 10px;
border-radius: 4px;
}
dt {
margin-bottom: 10px;
}
.error-message {
color: #ff3300;
}
myapp/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^search/', views.search, name='search'),
url(r'^mentions/', views.mentions, name='mentions'),
]
If you do not save the tweet search results in the database, the following is not necessary, but just in case it is described in views.py. We will use SQLITE, so leave the basic settings.py as the default.
myapp/models.py
from django.db import models
class Supermodel(models.Model):
user_name = models.CharField(max_length=140)
user_id = models.CharField(max_length=140)
user_img = models.CharField(max_length=140)
user_text = models.TextField(null=True)
user_created_at = models.CharField(max_length=140)
def __str__(self):
return self.user_name
myapp/admin.py
from django.contrib import admin
from myapp.models import Supermodel
class SupermodelAdmin(admin.ModelAdmin):
list_display = ('id','user_id','user_name','user_img','user_text','user_created_at')
admin.site.register(Supermodel,SupermodelAdmin)
It looks like this.
After that, please migrate and run server.
Recommended Posts