djangoでGoogleカレンダーに予定を登録するアプリを作りたい【2】
前回から時間があいてしまって(引っ越しとかで忙しく)、色々忘れてしまってたのだけど、また一歩ずつ。
前回はきっと認証がとりあえずできた、ってところで終わってた??
- やりたいこと①予定の登録をできるようにする
- やりたいこと②予定の一覧を出せるようにする
- やりたいこと③予定の編集・削除をできるようにする
- やりたいこと④予定の一覧を他の人のGoogleカレンダーに登録できるようにする
- やりたいこと⑤ChatGPTと連携したい
みたいな感じで、とりあえずこの土日で①②ができるといいなという感じ。
【やりたいこと①予定の登録をできるようにする】
新しく作ったものは以下3つの関数。
ChatGPTに「djangoでGoogleカレンダーに予定を登録するプログラムを作りたいです。setting.pyとviews.pyとurls.pyに記載することと、必要なHTMLを教えてください。」という何とも曖昧な聞き方からのスタート。
あとはググったんだけど、参考URLを忘れてしまった・・・
メインの関数。
認証してるかの確認。してなければauthorizeを呼ぶ。
POSTなら投げられてきたFormの情報をGoogleカレンダーに登録する。
Googleの認証ページにリダイレクトし、アプリケーションにアクセスを許可するための関数。(by chatGPT)
これが何かいまだによくわかってない。setting.pyで
と入れてるので呼ばれてるもの。
ユーザーがGoogleの認証ページで承認した後にリダイレクトされるコールバック関数。(by chatGPT)
すんごい色々エラーが出て、それをひとつひとつChatGPTに聞きながら解決していくんだけど、一番時間がかかったのは
'str' object has no attribute 'keys'
これがもうずっと出て、認証してくれないって言う・・・
credential.jsonファイルがうまくセッションに入れられなくて・・・
文字列だとか辞書型だとかの言い回しがchatGPTの言うことがころころ変わって初心者の私は大混乱・・・
chatGPTへの問いかけの仕方が大事なんだなーと実感です。
最終的なview.pyはこちら。
で、見た目はともかくとして

こんなのができました。
雑すぎる備忘録・・・
備忘録つけながらだと余計に時間がかかるから並行してできなくて💦
いやほんと時間が溶ける~~~~~本日も気づいたら朝6時になってしまいました。
寝なきゃ~~~
djangoでGoogleカレンダーに予定を登録するアプリを作りたい【1】
DjangoをUdemyの
【徹底的に解説!】Djangoの基礎をマスターして、3つのアプリを作ろう!
でとりあえずかじってみたので、GCPとの連携にチャレンジしたいメモ。
【私のレベル】
・100本ノックでPythonを少しかじって、webスクレイピングを何となくと、データ操作を何となく。
・応用情報を学生時代にとって早10数年で、プログラミングとかをやるのはそれ以来ぶり(要はひよっこ以下)
・HTML/CSS/JavaScript等々雰囲気はわかるけどググりながらじゃないと書けない
【やりたいこと】
推し関連のイベントの情報をGoogleカレンダーにまとめたい。
登録された情報を任意のGoogleアカウントのカレンダーにエクスポートできるようにしたい。
同じイベントについては情報を更新できるようにしたい。
----------------------------
ではスタート。
(1)djangoの環境構築
(2)ChatGPTに「djangoでGoogleカレンダーに予定を登録するプログラムを作りたい」と聞く
→GCPで認証情報(クライアント ID、クライアント シークレット)を取得しろとのこと。
(3)以下のサイトを見ながら「クライアントID」と「クライアントシークレット」を発行。(結局これが何なのかは理解してない)
credentials.jsonはmanage.pyと同じフォルダに保存。
(4)Pythonコードの作成。
●ライブラリインストール
●setting.pyの編集
・appの追加(「calenderapp」を作りました)
・TEMPLATESにtemplatesフォルダの追加
・Googleの認証情報の追加
最後のURIって言うのがよくわからず。更にChatGPTに聞く。
すると
GOOGLE_CALENDAR_REDIRECT_URIは、Google Cloud Platform の認証情報設定で指定したリダイレクト URI と一致する必要があります。これは、ユーザーが認証を完了した後にリダイレクトされる URI です。一般的な場合、ローカル環境で開発している場合は、http://localhost:8000のようなローカルホストの URI を使用できます。ただし、本番環境にデプロイする場合は、実際のドメインやサーバーの URI を使用する必要があります。例えば、https://example.com/google-auth-callbackのような URI を使用できます。リダイレクト URI は、Google Cloud Platform の認証情報設定で許可されたものでなければなりません。許可された URI のリストに、開発中や本番環境で使用する URI を追加してください。
とのこと。いったん「http://localhost:8000」で設定しておく。
これでsetting.pyはおしまい。
●views.pyの編集
ChatGPTの言うままに。
# views.py
from django.shortcuts import render
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.discovery import build
import datetime
import pytzdef create_event(request):
if request.method == 'POST':
# Google Calendar API にアクセスするための認証フロー
flow = InstalledAppFlow.from_client_secrets_file(
'client_secret.json', ['https://www.googleapis.com/auth/calendar.events'])creds = flow.run_local_server(port=0)
# 認証情報をセッションに保存
request.session['google_token'] = creds.to_json()# Google Calendar API のクライアントを構築
service = build('calendar', 'v3', credentials=creds)# イベントの開始時間と終了時間を設定
start_time = datetime.datetime.now(pytz.utc)
end_time = start_time + datetime.timedelta(hours=1)# イベントのデータ
event = {
'summary': 'Test Event',
'description': 'This is a test event',
'start': {
'dateTime': start_time.isoformat(),
'timeZone': 'UTC',
},
'end': {
'dateTime': end_time.isoformat(),
'timeZone': 'UTC',
},
}# イベントをカレンダーに追加
event = service.events().insert(calendarId='primary', body=event).execute()return render(request, 'success.html')
else:
return render(request, 'create_event.html')
(ソースコードの上手い貼り方がわからない・・・)
timezoneを「Asia/Tokyo」とかにしてみる。
runserverしてみると、無いModuleが複数あったので、都度pipで補充していく。(この辺も全部ChatGPTに聞きながら)
create_event.htmlにPOSTで「登録する」ボタンを作る。
プログラムにエラーが出なくなったと思ったら次はGoogle側のエラー。
「エラー 400: redirect_uri_mismatch」
って言うのが出た。
GCPの方を色々いじってみたけど、結局私はこれで解決した。理由は不明。
まだまだエラーは続く。
次は「このアプリは現在テスト中で、デベロッパーに承認されたテスターのみがアクセスできます。」って出た。
これはGCPの「OAuth同意画面」のテストユーザを追加することで解決。
これで一応「The authentication flow has completed. You may close this window.」って言うのが出た。
長かった~~~~~
【Python】100本ノックやってます。p‐89
P-089: 売上実績がある顧客を、予測モデル構築のため学習用データとテスト用データに分割したい。それぞれ8:2の割合でランダムにデータを分割せよ。
pip install scikit-learn
して
from sklearn.model_selection import train_test_split
した上で
df_train, df_test = train_test_split(df_sales_customer, test_size=0.2)
【Python】100本ノックやってます。p‐87~p-88
P-087: 顧客データ(df_customer)では、異なる店舗での申込みなどにより同一顧客が複数登録されている。名前(customer_name)と郵便番号(postal_cd)が同じ顧客は同一顧客とみなして1顧客1レコードとなるように名寄せした名寄顧客データを作成し、顧客データの件数、名寄顧客データの件数、重複数を算出せよ。ただし、同一顧客に対しては売上金額合計が最も高いものを残し、売上金額合計が同一もしくは売上実績がない顧客については顧客ID(customer_id)の番号が小さいものを残すこととする。
P-088: 087で作成したデータを元に、顧客データに統合名寄IDを付与したデータを作成せよ。ただし、統合名寄IDは以下の仕様で付与するものとする。
・重複していない顧客:顧客ID(customer_id)を設定
・重複している顧客:前設問で抽出したレコードの顧客IDを設定顧客IDのユニーク件数と、統合名寄IDのユニーク件数の差も確認すること。
この二つめちゃくちゃ難しかった、、、何だろうはまった、、、
考え方としては
ダブっている人を抜かしたリストを作る。(名寄席顧客データ)
それと元の顧客リストを名前と郵便番号で内部結合すると。
そうするとダブった人のところにも残す人のcustomer_idが入ると。
難しくなさそうなのになんかはまった・・・
【Python】100本ノックやってます。p‐84~p-86
P-084: 顧客データ(df_customer)の全顧客に対して全期間の売上金額に占める2019年売上金額の割合を計算し、新たなデータを作成せよ。ただし、売上実績がない場合は0として扱うこと。そして計算した割合が0超のものを抽出し、結果を10件表示せよ。また、作成したデータに欠損が存在しないことを確認せよ。
スムーズな方法になってるかはわからないけど、昨日理解したapplyを使いこなしたくて使ってみた!あまり時間かからずできた!
P-085: 顧客データ(df_customer)の全顧客に対し、郵便番号(postal_cd)を用いてジオコードデータ(df_geocode)を紐付け、新たな顧客データを作成せよ。ただし、1つの郵便番号(postal_cd)に複数の経度(longitude)、緯度(latitude)情報が紐づく場合は、経度(longitude)、緯度(latitude)の平均値を算出して使用すること。また、作成結果を確認するために結果を10件表示せよ。
突然簡単になってびっくりだったけど、次へのつながりがあるのか。
P-086: 085で作成した緯度経度つき顧客データに対し、会員申込店舗コード(application_store_cd)をキーに店舗データ(df_store)と結合せよ。そして申込み店舗の緯度(latitude)・経度情報(longitude)と顧客住所(address)の緯度・経度を用いて申込み店舗と顧客住所の距離(単位:km)を求め、顧客ID(customer_id)、顧客住所(address)、店舗住所(address)とともに表示せよ。計算式は以下の簡易式で良いものとするが、その他精度の高い方式を利用したライブラリを利用してもかまわない。結果は10件表示せよ。
math.sin、math.cos、math.acosが分かれば問題なし。
mathにはデータフレームは渡せないからapply使わないといけない。
【Python】100本ノックやってます。p‐81~p-83
P-081: 単価(unit_price)と原価(unit_cost)の欠損値について、それぞれの平均値で補完した新たな商品データを作成せよ。なお、平均値については1円未満を丸めること(四捨五入または偶数への丸めで良い)。補完実施後、各項目について欠損が生じていないことも確認すること。
平均出して、fillna使う。
[inplace=True]をつけないと反映されないの不思議。要注意。
P-082: 単価(unit_price)と原価(unit_cost)の欠損値について、それぞれの中央値で補完した新たな商品データを作成せよ。なお、中央値については1円未満を丸めること(四捨五入または偶数への丸めで良い)。補完実施後、各項目について欠損が生じていないことも確認すること。
中央値出してfillna使う。
P-083: 単価(unit_price)と原価(unit_cost)の欠損値について、各商品のカテゴリ小区分コード(category_small_cd)ごとに算出した中央値で補完した新たな商品データを作成せよ。なお、中央値については1円未満を丸めること(四捨五入または偶数への丸めで良い)。補完実施後、各項目について欠損が生じていないことも確認すること。
小区分コードごとの中央値は出せるけど、それをNaNにどう入れれば・・・
大変だった、、、3~4時間悩んでしまった・・・
先に全部マージして、NaNのところに入れるということが思いつかず。
いまいちapplyの使い方がつかみ切れてなくて。
xをなんとするかが難しかった・・・
【Python】100本ノックやってます。p‐81~p-83
P-081: 単価(unit_price)と原価(unit_cost)の欠損値について、それぞれの平均値で補完した新たな商品データを作成せよ。なお、平均値については1円未満を丸めること(四捨五入または偶数への丸めで良い)。補完実施後、各項目について欠損が生じていないことも確認すること。
平均出して、fillna使う。
[inplace=True]をつけないと反映されないの不思議。要注意。
P-082: 単価(unit_price)と原価(unit_cost)の欠損値について、それぞれの中央値で補完した新たな商品データを作成せよ。なお、中央値については1円未満を丸めること(四捨五入または偶数への丸めで良い)。補完実施後、各項目について欠損が生じていないことも確認すること。
中央値出してfillna使う。
P-083: 単価(unit_price)と原価(unit_cost)の欠損値について、各商品のカテゴリ小区分コード(category_small_cd)ごとに算出した中央値で補完した新たな商品データを作成せよ。なお、中央値については1円未満を丸めること(四捨五入または偶数への丸めで良い)。補完実施後、各項目について欠損が生じていないことも確認すること。
小区分コードごとの中央値は出せるけど、それをNaNにどう入れれば・・・
大変だった、、、3~4時間悩んでしまった・・・
先に全部マージして、NaNのところに入れるということが思いつかず。
いまいちapplyの使い方がつかみ切れてなくて。
xをなんとするかが難しかった・・・