自分のツイートだけを保存する
結局のところ何のために利用するかはわからないですが、Djangoのフォーム・テンプレートなどの理解を進めるにはやっぱりTwitterAPIで遊ぶのが最適解なのではないかなと思っています。というか何回Twitter APIで遊ぶんだよ、っていうのはやめてください。自覚症状はあります。
Djangoプロジェクトを作成する
Python3.6を想定しているので仮想環境構築は楽するやつ。
$ python3 -m venv pyworks
$ ls pyworks/
$ . pyworks/bin/activate
既にDjangoがインストールされているものとして話を続けます。
(pyworks)$ pip install requests requests_oauthlib
(pyworks)$ cd pyworks
(pyworks)$ django-admin startproject tweetsave
(pyworks)$ cd tweetsave
(pyworks)$ python manage.py startapp myapp
ひとまず準備完了ですが、Twitter APIのキーなどは取得しておいてください。
各種基本ファイルの編集
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'),
)
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
urls.pyも同様で、冗長に書いてますが「メディアファイルの取扱」を今後するかもしれないので書いておこう、くらいの感じです。
from django.conf import settings
from django.conf.urls import url, include
from django.conf.urls.static import static
from django.contrib import admin
urlpatterns = [
url(r'^myapp/', include('myapp.urls',namespace='myapp')),
url(r'^admin/', admin.site.urls),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
myapp/ にはurls.py が存在しないので新規作成します。
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^', views.index, name='index'),
]
モデルの定義
今回はただひたすら自分のツイートをデータベースに保存しますので、シンプルです。
from django.db import models
class MyTweet(models.Model):
tweet_words = models.CharField(max_length=140)
created_at = models.DateTimeField(auto_now_add=True)
せっかくなので管理画面用も書いておきます。
from django.contrib import admin
from .models import MyTweet
class MyTweetAdmin(admin.ModelAdmin):
list_display = ('id','tweet_words','created_at')
admin.site.register(MyTweet,MyTweetAdmin)
フォームの作成
Django Formを利用しなくても全く問題ないんですが、せっかくなのでフォームを書きましょう。特にオプション的な記述はせず、ごくシンプルなフォームを生成しますので、たったこれだけ。
from django import forms
from myapp.models import MyTweet
class TweetForm(forms.ModelForm):
class Meta:
model = MyTweet
fields = ('tweet_words',)
widgets = {
'tweet_words': forms.Textarea()
}
ビューを書く
自分で言うのも何ですが、凄く冗長です。
from django.http.response import HttpResponse
from django.shortcuts import render, redirect
from django import forms
from myapp.models import MyTweet
from myapp.forms import TweetForm
from requests_oauthlib import OAuth1Session
import requests
import json
C_KEY = '++++++++++++++++++++++++++++++++'
C_SECRET = '++++++++++++++++++++++++++++++++'
A_KEY = '++++++++++++++++++++++++++++++++'
A_SECRET = '++++++++++++++++++++++++++++++++'
Post_API = 'https://api.twitter.com/1.1/statuses/update.json'
tw = OAuth1Session(C_KEY,C_SECRET,A_KEY,A_SECRET)
def index(request):
form = TweetForm(request.POST or None)
msg = request.POST.get('tweet_words')
url = Post_API
params = {'status': msg,'lang': 'ja'}
req = tw.post(url, params = params)
if request.method == 'POST':
if form.is_valid():
if req.status_code == 200:
timeline = json.loads(req.text)
form.save()
return redirect('myapp:index')
else:
contexts = {
'Error_message': 'API制限中',
}
return render(request, 'myapp/index.html', contexts)
return redirect('myapp:index')
result_text = MyTweet.objects.all().order_by('-id')
contexts = {
'form':form,
'result_text':result_text,
}
return render(request, 'myapp/index.html', contexts)
テンプレートを書く
の前に、静的ファイルのディレクトリを再確認。
myapp/templates/myapp/ にテンプレートファイルを配置します。CSSやJS等の場合も同様に、
myapp/static/myapp/css~ などとして配置します。
同一プロジェクト内に複数アプリケーションを配置する場合などに、名前の競合で見つからないよ!を防ぐためです。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% load static %}
<link rel="stylesheet" href="{% static 'myapp/css/style.css' %}" >
<link rel="stylesheet" href="{% static 'myapp/css/bootstrap.min.css' %}">
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
{% extends 'myapp/base.html' %}
{% block body %}
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="col-md-4">
<form action="{% url 'myapp:index' %}" method="post">
<div class="row">
{% for field in form %}
<label>{{ field.label_tag }}</label>
<label>{{ field }}</label>
{% endfor %}
<input type="submit" class="btn btn-primary" value="送信">
{% csrf_token %}
</div>
</form>
</div>
<div class="col-md-8">
{% include "myapp/result.html" %}
</div>
</div>
</div>
</div>
{% endblock %}
{% block body %}
<ul class="row">
{% for i in result_text %}
<li class="box clearfix">
<dl>
<dt> {{ i.created_at }}</dt>
<dd>{{ i.tweet_words }}</dd>
</dl>
</li>
{% endfor %}
</ul>
{% endblock %}
migrations / migrate
お約束のやつをやります。
(pyworks)$ python manage.py makemigrations myapp
(pyworks)$ python manage.py migrate
必要に応じて
(pyworks)$ python manage.py createsuperuser
実行する
runserverして、実行します。
なんと不毛なアプリケーションの誕生です。