[PYTHON] A barren Twitter posting client that saves only your tweets

Save only your tweets

After all, I don't know what it's used for, but I think playing with the Twitter API is the best solution to improve your understanding of Django's form templates. Or rather, don't say how many times you play with the Twitter API. I have a subjective symptom.

Create a Django project

Since Python 3.6 is assumed, building a virtual environment is easy.

$ python3 -m venv pyworks
$ ls pyworks/
$ . pyworks/bin/activate

Let's continue assuming that Django is already installed.

(pyworks)$ pip install requests requests_oauthlib
(pyworks)$ cd pyworks
(pyworks)$ django-admin startproject tweetsave
(pyworks)$ cd tweetsave
(pyworks)$ python manage.py startapp myapp

It's ready for the time being, but please get the Twitter API key etc.

Editing various basic files

Add (replace) the last line of settings.py as follows. As for the media, it's easier to write about it later, so it's okay to skip it this time. I wonder if I should write only the static file part.

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')

The same is true for urls.py, which is written redundantly, but I think I'll write it because "handling of media files" may be done in the future.

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)

urls.py does not exist in myapp /, so create a new one.

myapp/url.py


from django.conf.urls import url
from . import views


urlpatterns = [
    url(r'^', views.index, name='index'),
]

Model definition

This time, I just save my tweets in the database, so it's simple.

myapp/models.py


from django.db import models

class MyTweet(models.Model):
    tweet_words = models.CharField(max_length=140)
    created_at = models.DateTimeField(auto_now_add=True)

Since it is a big deal, I will write it for the management screen as well.

myapp/admin.py


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)

Form creation

It's okay if you don't use Django Form, but let's write the form. It will generate a very simple form without any optional description, so this is all.

.myapp/forms.py


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()
        }

Write a view

Whatever I say myself, it's very verbose.

myapp/views.py


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 restricted',
                    }
                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)

Write a template

Double-check the static file directory before.

スクリーンショット 2017-05-16 11.46.10.png

Place the template file in myapp / templates / myapp /. Similarly for CSS and JS, Place it as myapp / static / myapp / css ~ etc.

If you have multiple applications in the same project, you can't find them due to name conflicts! This is to prevent.

myapp/base.html


<!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>

myapp/index.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="Send">
              {% csrf_token %}
            </div>
        </form>
      </div>
      <div class="col-md-8">
        {% include "myapp/result.html" %}
      </div>
    </div>
  </div>
</div>
{% endblock %}

myapp/result.html


{% 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

I will do the promised one.

(pyworks)$ python manage.py makemigrations myapp
(pyworks)$ python manage.py migrate

If necessary

(pyworks)$ python manage.py createsuperuser

Execute

runserver and run.

スクリーンショット 2017-05-16 11.51.18.png

What a barren application is born.

Recommended Posts

A barren Twitter posting client that saves only your tweets
I tried to make a system that fetches only deleted tweets
Get only image tweets on twitter
[Python] Created a Twitter bot that generates friend-like tweets using Markov chains
Run it in your browser. Twitter client made with bottle (POST only
Your own Twitter client made with Django
Create a bot that boosts Twitter trends