なぜ8日をようかというのか疑問に思って調べてみた。
なぜ8日をようかと読むのか
yahoo知恵袋からです。 https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1239742622
八を「や」、日を「か」と読んで「やか」となったのが、時が経つにつれて「やうか」に変化し、それが現在では「ようか」と読まれるようになりました。 蛇足かもしれませんが…八を「はち」と読むのは音読みで、「や」と読むのは訓読みです。かつ日を「にち」と読むのは音読みで、「か」と読むのは訓読みです。「ようか(やか)」は「八日」を単に訓読みで読んだだけと言えます。
goo辞書 https://dictionary.goo.ne.jp/jn/226193/meaning/m0u/
《「やか」の音変化》
どうやら、「やか」からの変化で良いみたいです。
「やか」から「ようか」に変化するとか、ほんとに?って疑いたくなってしまいますね。
真ん中の「う」がなんで入るかわからないですもん。
おなじように「7日」を「なのか」の「の」がなぜ入っているのかとか。
これはあれですかね。言いやすいからでしょうか?(これについては全く調べてないです)
日本語は不思議ですね。
左側に表示するナビゲーションメニューについて調べたときに参考にしたサイト
ナビゲーションのメニューがまとまっているサイトです。
こういったサイトはよく見ます。とても助かりますね。
この中で使えそうだなと思ったものを紹介したいと思います。
まずはこれです。
https://codepen.io/MrsColombo/pen/mEeQwy
- htmlがきれいで、templateの構文を使ってforでリストを生成できそうだと思った
- cssで書かれているので、scssに直しやすい
- jsが複雑じゃない
もちろん、少し修正は必要ですが、少ない工数できれいなメニューを作れそうです。 (左側に固定するメニューではないようで残念です…)
明るいサイトに合いそうです。
どんどん紹介します。
これですが、見た目はよいですが、少し片手落ちだと思いました。
https://codepen.io/maggiben/pen/rCIFu
クリックした際に、右側の矢印がアニメーションされない。つまり、なんであるのかわからないです。
このくらいならcssを追加して対応できそうです。
リストがabsolute指定されているので、要件によっては少し修正が必要かもしれません。
fixedではないということは、スクロール時に残らないということです。
スクロールするとリストが途切れているように見えてしまいます。
参考にする場合はcssの変更が必要そうですね。
いいかな?と思いましたがコードを見たら大変そうだったやつです。
https://codepen.io/andytran/pen/rsegt
haml(htmlではない)で書かれているので、htmlに直したほうが良いでしょう。 hamlで書きたい場合はそのままで無問題
ほとんどclassやidを使っていないので、独自定義するスタイルに影響しそうです。 (reset.scssとか、cssフレームワークとか)
↓のように、タグにスタイルを入れているので、ページ内でリストを使っている場合は影響しそうです。 (許容範囲内かな?)
nav ul li a { display: block; padding: 10px 15px; color: #fff; text-decoration: none; transition: 0.2s linear; border-left: 2px solid transparent; } nav ul li a:hover { background: #fff; padding-left: 20px; border-left: 2px solid #1abc9c; color: #1abc9c; }
右側の矢印がアニメーションしてません。これは修正ですね。
参考文献という英単語を調べたときに使ったサイト
結論から
参考文献 = 「Works Cited」 or 「reference」 or 「bibliography」
英単語を調べるのに、以下のサイトが役に立ちました。 https://eikaiwa.dmm.com/uknow/questions/19454/
といってもDMM英会話なんですけど。
読んだ時期によって解答が消えてたりするかもしれないので、引用をのせますね。
大学のレポートの最後に付ける、レポート内で使った資料のリストのことを、Works Citedと言います。worksは、もちろん仕事だったり研究だったりを示しますので、それが「文献」となります。一方「参考」というのは「(自分が)参考にした」つまり「(文献が)参考にされた」という、分詞形容詞-edを使ってcitedとなり、worksの後ろに付けます。MLAスタイルでも、APAスタイルでも、全てレポートの最後にはworks citedを付けてくださいね。
この解答が一番役にたったのですが、もちろんこの解答が正しいのかどうかも調べてます。
まずは、citedが「引用」「参考」という意味で使われるのかどうか。
これは英辞郎on webで調べました。 https://eow.alc.co.jp/search?q=%22cite%22&ref=hk
ついでにweblioでも調べてます。 https://ejje.weblio.jp/content/cite
ここまでで、どうやら「citeという単語が参考という意味で使われる」というのが解答が正しそうというのがわかりました。
次に、「レポートの最後でworks cited」と使うのかどうかを調べました。
参考文献がどんな使われ方をするのかは、調べなくてもよかったのですが、解答を読んで気になったので調べてみました。
まず↓のサイトでは「works」や「cite」という単語で検索しても出てきませんでした。
http://user.keio.ac.jp/~kiyota/kozo/Courses/References.html
Weblio英語勉強コラムのページです。 http://english-columns.weblio.jp/?p=5632
MLA(Modern Language Association style)は使用頻度が特に多い文献スタイルで、文学や言語の分野での使用が多くみられます。参考書目としての表記は「Works Cited」です。
ヒットしましたね。
ですが、そのすぐ下に↓のような文がありました。
APA(American Psychological Association)はMLAと比べ一般的に読みやすく表記されたスタイルで、社会科学やビジネスの分野での使用が多く見られます。参考書目としての表記は「Reference」です。
どうやら、referenceという単語もあるみたいです。
さらに、MLAフォーマット、APAフォーマットのように、どのように参考文献を書くかによって単語が変わるようです。
すごく面倒です。統一してほしいですよ…
ここまででやめても良かったのですが、ついでに英語サイトを調べてみました。
「works cited reference」で調べたときに出たサイトです。
http://www.citethisforme.com/blog/2017/06/27/69196
どうやら、「works cited」「reference」の他に「Bibliography」という単語もあるようです。
英語は読めないので、google翻訳の訳ですが、大方このような感じでした。
「bibliographyは、論文を書く際に参考にしたものだけではなく、準備段階で参考にしたものも含める」
のだそうです。
結局、参考文献という単語は「works cited」か「reference」を使うと良いと思います。
「bibliography」の場合はもっと準備段階も含めたい場合に使うと良いと思います。
Djangoのモデルに定義していないフィールドを追加する方法
こんな感じのModelを定義しているときに、追加でフィールドを入れたくなったときがありました。
class Sample(models.Model): uuid = models.UUIDField(unique=True) created_at = models.DateTimeField(auto_now_add=True) modified_at = models.DateTimeField(auto_now=True) class Meta: db_table = 'sample'
いれたフィールドをtemplateで使用して画面に表示するといった具合で使いました。
↓のコードで対応することができました。
model.__setattr__('icon', 'icon/' + sample.author.username)
iconを表示する際にusernameの前にフォルダ名が必要だったのです。
ですが、Djangoのタグを使っていて文字列の連結ができないし、カスタムタグで拡張することもできない。(少なくとも私には見つけられませんでした。)
最初はmodelはorderdictだからmodel['icon']
で対応できると思ったのですが、ダメでした。
Djangoでページングを表示するための関数
Djangoでページング処理を作成する際に作った関数を紹介します。
コードの紹介になるので、紹介はコードにコメントにて行います。
前後のページを表示するための関数
# self.limit: データ表示数 def page_data(self, count, page): # count: データ数 # page: 現在のページ番号 current_page = page if count == 0 or count < self.limit: # データ数が0の場合に対応 prev_page = 1 next_page = 1 page_limit = 1 else: # ページの最後尾の数値をみつける。 page_num = int(count / self.limit) # 割り切れない場合は+1して、あまりを表示できるようにする page_limit = page_num if count % self.limit == 0 else page_num + 1 # 前のページが1未満にならないようにする prev_page = 1 if (current_page - 1) < 1 else current_page - 1 # 次のページがページ番号の限界を超えないようにする next_page = page_limit if (current_page + 1) > page_limit else current_page + 1 return { 'prev': prev_page, # 前のページ 'current': current_page, # 現在のページ 'next': next_page, # 次のページ 'limit': page_limit, # ページの限界 'next_page': 'home', # {% url next_page %}のように使用する }
テンプレートのコードをなくしてしまったので紹介できません。orz
return
で返しているデータからhtmlタグを作成するとできます。
範囲でページを表示するための関数
もう少しスマートに作成する方法がありそうです。
def get_page_list(self, data_size, current_page): PAGE_RANGE_SIZE = 5 # ページ番号を表示する数 if data_size % self.limit == 0: page_limit = int(data_size / self.limit) else: # 割り切れない場合は+1して、あまりを表示できるようにする page_limit = int(data_size / self.limit) + 1 page_list = [] # ↓ startとendを計算して、あとでループに使用する start = current_page - 2 if start < 1: start = 1 end = start + PAGE_RANGE_SIZE if end > page_limit: end = page_limit + 1 # ↓ を入れないとページ番号がずれる start = end - PAGE_RANGE_SIZE if start < 1: start = 1 # ページ番号を取得する for pi in range(start, end): page_list.append(pi) return { 'current': current_page, # 現在のページ 'limit': page_limit, # ページ番号の限界 'nums': page_list, # ページ番号のリスト 'next_page': 'home', # {% url next_page %}のように使用する }
テンプレートを作成する。
bulmaというcssフレームワークを使用していますが、基本は同じかと思います。
横に長くなってしまって見づらいです。どうにかしたいところです。
<ul class="pagination-list"> {% if page.current != 1 %} <!-- 現在のページが先頭なら表示しない --> <li><a class="pagination-link" href="{% url page.next_page %}?{%query_transform request page=1%}"><<</a></li> {% endif %} {% for num in page.nums %} <li> <!-- 現在のページの場合はクラスを追加する --> <a class="pagination-link {% if num == page.current %} is-current {% endif %}" href="{% url page.next_page %}?{%query_transform request page=num%}">{{num}}</a> </li> {% endfor %} {% if page.current != page.limit %} <!-- 現在のページが最後尾なら表示しない --> <li><a class="pagination-link" href="{% url page.next_page %}?{%query_transform request page=page.limit%}">>></a></li> {% endif %} </ul>
query_transform
というのは独自に作ったtagです。
これを使うと、クエリストリングをスマートに作成できます。
@register.simple_tag def query_transform(request, **kwargs): updated = request.GET.copy() for k, v in kwargs.items(): updated[k] = v return updated.urlencode()
これはどこかの記事で紹介していた気がします。
stackoverflowで載っていたものを使っています。
pythonでjwtを使う際に作ったutilについて
作成したjwtのutilを紹介します。
作成したutilですが、まだまだ修正途中のものです。使用する場合は注意してください。
jwtについての詳細についてはこちらを参照してください。
コードと解説の距離が離れると読みづらいと思いますので、できる限りコメントを書きました。
そちらを見てください。
import datetime from datetime import datetime, timedelta import jwt import pytz class JwtContent(object): JWT_EXPIRE_DAY = 1 JWT_ALGORITHM = "HS256" JWT_SECRET_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" JWT_COOKIE_NAME = "Authentication" COOKIE_EXPIRE_FORMAT = "%a, %d-%b-%Y %H:%M:%S GMT" class JwtUtil(object): @staticmethod def create_token(payload, is_revoke=False): """ payloadを使用してjwtトークンを発行する :param is_revoke: Trueにするとtokenを有効期限切れにする :param payload: dict object :return: jwtでエンコードされたトークン """ timezone = pytz.timezone('Asia/Tokyo') now = datetime.now(tz=timezone) if is_revoke: delta = timedelta(days=-JwtContent.JWT_EXPIRE_DAY) else: delta = timedelta(days=+JwtContent.JWT_EXPIRE_DAY) result = now + delta payload["exp"] = result encode_data = jwt.encode( payload, JwtContent.JWT_SECRET_KEY, algorithm=JwtContent.JWT_ALGORITHM ) return encode_data.decode('utf-8') @staticmethod def is_expired_token(jwt_token): if jwt_token is None: return True, None, None try: decode_data = jwt.decode( jwt_token, JwtContent.JWT_SECRET_KEY, algorithms=[JwtContent.JWT_ALGORITHM] ) return False, decode_data, None except jwt.ExpiredSignatureError as e: # 有効期限切れ return True, None, e except jwt.InvalidTokenError as e: # decodeが実行できなかった return True, None, e except Exception as e: return True, None, e @staticmethod def is_expired_session_token(request, cookie_name): """ requestからトークンのクッキーを取り出してそのクッキーの有効期限を判定する :param cookie_name: :param request: :return: 成功時デコードされたデータ(dict object). 失敗時True """ jwt_token = request.COOKIES.get(cookie_name) return JwtUtil.is_expired_token(jwt_token) @staticmethod def set_jwt_cookie(response, jwt_cookie_data, cookie_name): """ responseオブジェクトにjwtトークンキーをセットする jwtのexpireはcommon.config.JWT_EXPIRE_DAYによって変わる また、タイムフォーマットはAsia/Tokyoのゾーンとしている セキュリティのため、httponlyをtrueにしている :param response: :param jwt_cookie_data: :return: """ timezone = pytz.timezone('Asia/Tokyo') expire_datetime = datetime.now(tz=timezone) + timedelta(days=+JwtContent.JWT_EXPIRE_DAY) expire_datetime_str = expire_datetime.strftime( JwtContent.COOKIE_EXPIRE_FORMAT ) response.set_cookie( cookie_name, jwt_cookie_data, expires=expire_datetime_str, httponly=True ) return response @staticmethod def delete_jwt_cookie(response, cookie_name): response.delete_cookie(cookie_name) return response
データが存在しない場合にデータを追加するSQL
テーブル内にデータが存在しない場合に限って、データを追加する方法を紹介します。
クエリについては日本語で解説をするよにも、まずはコードを見たほうが早いと思うので、先に載せます。
こちらが、データを追加するクエリです。
INSERT INTO tag ( name, created_at, modified_at ) SELECT 'test', now(), now() WHERE NOT EXISTS ( SELECT 1 FROM tag WHERE name = 'test' )
上記のクエリは、tagを追加する際に、すでにタグが存在していたら追加しないというクエリです。
これは、select insert文というものです。そして、not existを使って、存在しない場合を条件で追加しています。
where 1で真になるので、データがある場合でinsertが実行されます。
おまけ
一般的なinsert文はこのようなクエリだと思います。
insert into tag ( xxxx, yyyy, zzzz ) values ( 1, 2, 3 )
じゃあ、このクエリにwhereをつければよいのでは?と考えるかもしれませんが、それは構文エラーになります。
一応クエリを載せておきます。
INSERT INTO tag ( name, created_at, modified_at ) values ( 'test', now(), now() ) WHERE NOT EXISTS ( SELECT 1 FROM tag WHERE name = 'test' )