diadia

興味があることをやってみる。自分のメモを残しておきます。

Javascriptメモ

参考url : https://developer.mozilla.org/ja/docs/Web/JavaScript

関連記事


基本的な使い方

使い方はhtml上に直接javascriptを書く方法と、htmlファイルとは別に.jsとして保存してjavascriptのコードを書く方法がある。後者の方法はメンテナンス性の向上が得られる

htmlに直接記述する方法

<body>
    <script>
        console.log("Hello World!")
    </script>
</body>

外部ファイルとして.jsファイルを設ける方法

html

<body>
    <script src="myscript.js"></script>      
</body>

myscript.js

 console.log("Hello World!")    

HTMLのメモ まとめ

関連記事



本題

<title>タグ

ブラウザに表示されるタブの文字を変更するにはどうすればいいのか?

→htmlのheadのタイトルを変更するだけ。

そのほか、ブックマークの表示名や検索エンジンの検索結果のタイトルになる

 

<form>タグ関連

  • 種類<input>,<textarea>,<select>がある。
  • <input>は閉じタグいらないけど、<textarea>は閉じタグが必要という違い
  • <input>の内容を示すには外からを使う。
  • <input>内ではplaceholder=""を使う。
    • 参考<label>使い方

      <label for="name">お名前</label>
      
      <input id="name" type="text" >
      

      <select>について

      選択肢として選ばせることができる機能。

      簡単な使い方:

      <select>
      
      <option>オプション1</option>
      
      <option>オプション2</option>
      
      </select>
      

       

      ラジオボタンについて

      比較的選択肢が少ない場合、セレクトを用いるよりラジオボタンを導入するほうがユーザにとっては使いやすくなる。

      簡単な使い方

      <label>区分</label>
      
      <input id="personal" type="radio" name="区分" value="個人の方">
      <label for="personal">個人の方</label>
      <input id="corporation" type="radio" name="区分" value="企業の方">
      <label for="corporation">企業の方</label>
      

      ブラウザ上で<>の表示をさせる方法

      &lt;  &gt;

       


      ブラウザ上からクリックでダウンロードさせる方法

      ブラウザ上にある画像をユーザーがクリックすることでダウンロードする仕組みを作る場合は、

      <a>中にhrefとdownloadを記述してやれば良い

      <a href="path" download="path">
      <a href="image/001.jpg" download="image/001.jpg">
      <li><a href="image/001.jpg" download="image/001.jpg"><img src="image/001.jpg"</a></li>

Userモデル関係を整理してみる まとめ

USERモデル関係 他の記事


本題

そもそもUserモデルとは

djangoを勉強していて急に出てくるUserという言葉。ドキュメント内でそれらが当たり前のように様々な説明に絡む。
もやもやした。
勉強してきて少しずつ分かってきたことを記載する。

まずdjangopython manage.py makemigrations, python manage.py migrateしたときにUserモデルが作られる。Userモデルという表現は馴染みにくいけど、データベースやテーブルと考えるとよい。Userモデルはユーザーのデータベースであって、こちらにユーザ情報を追加したり、削除して管理する。わけもわからずpython manage.py createsuperuser とかコードを叩いた経験があるけど、その結果Userというところにスーパーユーザーの情報が登録されているのを確認できる。テーブルのカラムにあたるものを記入されることを要求されたり、adminにスーパユーザとしてデータ登録されている事実を踏まえるとデータベースだと認識できると思う。勉強開始当初この認識を妨げ、ユーザモデルをもやもやにする理由は以下にあると思う。
普通はmodels.pyに自分で作りたいデータベース(テーブル)の枠組みを記述し、makemigrations,migrateを経てデータベースを作成する。Userモデルだけはこの一連の処理をしない。自分ではデータベースを作っていない認識になってしまう。
ユーザモデルだけは予め作ってくれるものだ、と認識すると初学者にとって理解の助けになる。



カスタムUserモデル

これは上記のスタートプロジェクトしたときに作られるUserモデルと対立するモデルと考えれば良い。予め作ってくれるUserモデルではなく、自前で(models.pyでクラスを規定、makemigrations,migrate)作ったモデル。カスタムと呼ばれる所以は自動的に作られるUserモデルでは役割不足なので自分のプロジェクトにあったUserモデルを作るところにある。

プロジェクト途中でユーザモデルを変更するのは大変らしい。
そこでドキュメントではプロジェクト開始時にカスタムUserモデルを作成しとくこととアドバイスしている。このときにAUTH_USER_MODELもmakemigrations migrate前に設定すること。
プロジェクトの開始時にカスタムのユーザーモデルを使用する



AUTH_USER_MODEL

これも何が何だか分からない、何のために存在しているか分からない印象だった。
これは上記2つのモデルが存在することで必要になるものだ。自前のカスタムUserモデルを作った場合、既存のUserモデルもあるのでユーザーモデル一つのプロジェクトで併存してしまう。どっちのモデルを使いますという宣言がAUTH_USER_MODELです。
使い方一例:AUTH_USER_MODEL=Myapp.MyUser

カスタムの User モデルを置き換える


get_user_model()

これも一体何のために存在するかわからなかった。ドキュメントには以下のように書いてあるけどこれを使う場面と結びつかないから自分は困った。

"""User を直接参照する代わりに、django.contrib.auth.get_user_model() を使ってユーザモデルを参照すべきです。このメソッドは現在アクティブなユーザモデルを返します -- 指定されている場合はカスタムのユーザモデル、指定されていない場合は User です。"""

https://docs.djangoproject.com/ja/2.1/topics/auth/customizing/#referencing-the-user-model

自分はget_user_model()をUserモデルデータベースを編集するときに使うイメージにした。
User=get_user_model()とすると、今使われているUserモデルを返してくれるので以下のようにできる。
User.objects.create_user(**********) みたいな使い方をする

formの入力データを返す方法(cleaned_data)

フォームによるデータの返す準備、手続き

forms.Formを用いたデータを表示させるには以下のコマンドが必要になる。

form=HogeForm(request.POST)
if form.is_valid()
    form.cleaned_data

で単純にrequest.POSTを入れたFormにcleaned_dataをかけ合わせれば入力データが返されるわけではないことがわかった。
参照元
https://docs.djangoproject.com/ja/2.1/topics/forms/#field-data

フォームで送信されたデータが何であっても、is_valid() を呼び出して正常に検証されると(そして``is_valid()`` が True を返すと)、検証されたフォームデータは form.cleaned_data ディクショナリに格納されます。 このデータは Python の型にうまく変換されています。

つまりis_valid()の結果がTrueのとき、form.cleaned_dataに情報が格納される。
もっと言えばis_valid()を挟まないと入力データを参照することは出来ない。


データの取り出し方

返すデータは辞書型なので、通常のようにキーを入れれば値が返される。

form.cleaned_data["name"]

forms.py外で定めなければならないもの

forms.Formを利用するにあたって必ずhtml上で定めなければならない事がある。
これはforms.pyで定めることが出来ず、どうしてもhtml上で記述しないといけないということだ。

https://docs.djangoproject.com/ja/2.1/topics/forms/#html-forms

As well as its <input> elements, a form must specify two things:

どこで: ユーザーのインプットに対応するデータの宛先となるべきURL
どのように: データが返される方法として使われる HTTP メソッド
︙
また、フォームのデータが <form> の action 属性によって指定された URL - /admin/ - に送信されるべきこと、そして method 属性によって指定されたHTTP メカニズム - post - を使って送信されるべきこともブラウザーに伝えています。

    ドキュメントのこれらの記述からFormを使う際は2点定めなければいけない。
  • フォームで送られたデータの宛先(つまりURLでありaction)の決定
  • どのように送られるデータが送信されるか

また同一ドキュメント内に以下の記述がある。

<form> や送信ボタンを含んで いない ことに注意してください。私たち自身が、これらをテンプレート内で提供する必要があります。


というわけでtml上で必ずmethodとactionは定めること。
formタグ、送信ボタンの設置を記述すること。
忘れないように。

django:リクエストヘッダの内容を取得する まとめ

POST/GETの判別
HTMLフォームから送信されたパラメータが、どのメソッドで送信されたかを調べる方法

if request.method == 'POST':
# POSTでパラメータを送ってきたときの処理
...
else:
# GETでパラメータを送ってきたときの処理
...


HTTP リクエストヘッダーを取得する
User-Agentなど、クライアントが送信する情報を取得したいときも、同じようにそれ用のDictionaryがある

userAgent = request.META.get('HTTP_USER_AGENT', None)

これを少し変えるとユーザーのIPも取得できる。

def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

ミドルウェアまとめ

このページにミドルウエアで学んだことを集めていく。
まずミドルウエアはなにか?

ミドルウェアは、Django のリクエスト/レスポンス処理にフックを加えるためのフレームワークです。これは、Django の入力あるいは出力をグローバルに置き換えるための、軽量で低レベルの「プラグイン」システムです。

https://docs.djangoproject.com/ja/2.1/topics/http/middleware/#middleware

自分のイメージでは、requestを使う際に他の情報も追加して取り扱いたいときに活躍するのがミドルウエア。例えば、ユーザー認証やセッション類。


使うための準備
いろいろ設定が必要。機会があればまとめる。


ミドルウエアの種類
Cache middleware
Common middleware
GZip middleware
Conditional GET middleware
LocaleMiddleware
MessageMiddleware
Security middleware
Session middleware
Site middleware
Authentication middleware
CsrfViewMiddleware
XFrameOptionsMiddleware



セッションミドルウエアについて
 セッションミドルウエアの設定をするとrequestにセッション属性を持たすことができる。request.sessionで扱い、辞書型データを扱うように処理する。
https://docs.djangoproject.com/ja/2.1/topics/http/sessions/#using-sessions-in-views

django[データオブジェクトの操作まとめ]

関連記事

本題:データオブジェクトの操作まとめ


動画をみて勉強していたが、ついていけなくなった。
打開策としてドキュメントを読んでみようと思う。
最初は読んでもわからなかったことも今なら少しわかることもあるだろう。

クエリを作成する | Django documentation | Django
データ系の操作ががわからない。
操作といえばデータの作成、変更、削除、検索取り出しだ。
この辺を見ていく。


データの作成方法

djangoドキュメントでは自分が思うデータをデータオブジェクトと読んでいる。
データオブジェクト=レコード。
データオブジェクト(オブジェクト)を作成する方法は2つ

#① 
>>> from blog.models import Blog
>>> b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
>>> b.save()
#②
b= Blog.objects.create(name='Beatles Blog', tagline='All the latest Beatles news.')


オブジェクトに対する変更を保存する

#save()が行われないと変更が保存されない。
>>> b.name = 'New name'>>> e.delete()
>>> b.save()
この変更は変更したいレコード(この場合はb)をまずデータベースのテーブルからとってきている前提がある。
テーブルから任意のデータオブジェクトを取ってくることを「オブジェクトを取得する」とする。

オブジェクトを削除する

オブジェクトを取得するは説明事項が多いので先に削除から確認する。

>>> e.delete()
(1, {'weblog.Entry': 1})
#save()しなくても消えてしまう
#また一つじゃなくて複数消すことや全部消すこともできる
>>> Entry.objects.filter(pub_date__year=2005).delete()
(5, {'webapp.Entry': 5})
>>>Entry.objects.all().delete()

モデルのインスタンスを複製する

クエリを作成する | Django documentation | Django
モデルインスタンスを複製するためのビルトインメソッドはありませんが、すべてのフィールドの値を複製した新しいインスタンスを作成することは簡単にできます。最もシンプルなケースでは、pk を None にセットします。ブログの例を使用すると

blog = Blog(name='My blog', tagline='Blogging is easy')
blog.save() # blog.pk == 1

blog.pk = None
blog.save() # blog.pk == 2
#継承している場合はpk と id の両方を None にセットする必要がある。
class ThemeBlog(Blog):
    theme = models.CharField(max_length=200)

django_blog = ThemeBlog(name='Django', tagline='Django is easy', theme='python')
django_blog.save() # django_blog.pk == 3

django_blog.pk = None
django_blog.id = None
django_blog.save() # django_blog.pk == 4

オブジェクトを取得する

オブジェクトを取得すると言っても上の例のように、オブジェクト1つだけと限らず、3つだったり、条件を満たすものだけ取得する場合がある。
https://docs.djangoproject.com/ja/2.1/topics/db/queries/#retrieving-objects

>>> x=Cart.objects.create()
>>> x
<Cart: 11>  #データオブジェクト(レコード)は<モデル名:ID番号>で表される。

>>> z = Cart.objects.filter(id=11)
>>> z
<QuerySet [<Cart: 11>]> #結論:フィルターをかけるとクエリセットが返ってくる


#クエリセットからどうやってオブジェクトを引き出すか?
>>> z.first()
<Cart: 11> #結論:クエリセットにfirst()をかけるとオブジェクトを引き出せる

>>> z.get(id=11)
<Cart: 11> #結論:クエリセットにget()をかけるとオブジェクトを引き出せる

次に気になるのはどうやってデータオブジェクトのフィールドを参照するのか?
答えはデータオブジェクト(レコード)にカラムを指定するとフィールドを参照できる。
ただすべてこの限りではない。

>>> x.id
11
#結論:データオブジェクトにカラムをかけ合わせればフィールドを参照できる

# フィールドに入ってない情報を参照するとどうなるか?
>>> x.user #結論:何も返ってこない
>>> type(x.user)
<class 'NoneType'>


#注意:ManyToManyFieldとしている場合の参照方法
#前提:ManyToManyFieldにいくつか製品を予め登録してあります
>>> x.products
<django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager object at 0x10ec8cef0>

#解決策:fieldに複数入っているものを選択する(テーブルからクエリセットするように)
>>> x.products.all()
<QuerySet [<Product: camera>, <Product: TV>, <Product: cellphone>, <Product: Hair dryer>]>

>>> y=x.products.all()
>>> for t in y:
...     print(t)
... 
camera
TV
cellphone
Hair dryer

#クエリセット状態ならfor構文を使用することができる。
>>> for t in y:
...     print(t.price)
... 
39.99
39.99
39.99
39.99

もっと大きな視点で考えてみる。
データを作成する場合

data_object = Blog(name="Hoy,Buen dia", content=" Hoy nos vemos .el vive ....." )
data_object.save()
または
data_object=Blog.objects.create(name="Hoy,Buen dia", content=" Hoy nos vemos .el vive ....." )

こんな感じで作ってきた。これはviews.pyに組み込んだり、django のshellで実行したりしてデータオブジェクトを作成するパターンだ。もちろん他にも方法がある。adminからデータを作成する場合もある。確認はそれぐらいにしておいて、自分が気づいたのは以下のこと。上記の方法はデータ作成主体が自分またはサイト運営者である。ただデータを作成する主体はユーザもいる。このユーザによって作成され、特定の場合の為にシグナルやm2m_changedっていうキーワードが必要になってくるのではないか?

ユーザがデータ作成するときにsignalsが必要になるという過程に基づいて勉強を進める。
signals
Signals | Django documentation | Django


pre_save()について
https://docs.djangoproject.com/ja/2.1/ref/signals/#pre-save
リレーション関係のものは以下のような感じで、定義とともにコネクトの一文を入れることが原則のようだ。

def pre_save_total(sender, instance, *args, **kwargs):
obj = instance
.....

pre_save.connect(Hoge, sender=class_name)




get_queryset()について

本来の使い方かどうかはわからないけれども、以下のように使っている。
その使い方は、クエリセットの修正だ。
ListViewにはget_queryset()なるものがあるらしい。
ListViewをそのまま使うとget_queryset()の結果が返される。
get_queryset()はClass.objects.all()で作られている。自分のほしいクエリセットを返したければget_queryset()を上書き保存する必要がある。
この上書き時にget_queryset()を書くことになる。
これはデータベースの検索のようなときに使う。



・Methods that do not return QuerySets
https://docs.djangoproject.com/ja/2.1/ref/models/querysets/#methods-that-do-not-return-querysets
データベースを扱う上で命令の結果がクエリセットで返ってくるか、データオブジェクトで返ってくるかは非常に重要で覚えるべきものだ。
だからShellを用いて結果がクエリセットかデータオブジェクトかをメモして覚えていた。
しかしながらdjangoのドキュメントにその区別を明確にするものがあった。
クエリセットで返すものとその他で区別されている。
今回はドキュメントの中でよく目に触れるものを列挙してみる。
get()
オブジェクトを返す
create()
オブジェクトを返す
get_or_create()
オブジェクトを返す
update_or_create()
count()
整数を返す
latest()
first()
last()
exists()
delete()

models.Manager の説明が書いてあった

自分がmodels.Managerに出会ったのは、クラスを継承(拡張?)するときだ。
これについての説明があったのでソースを保持する。
マネジャ — Django v1.0 documentation


Managerはデータベースクエリ操作をdjangoモデルに提供しているインターフェース。自分が見たのはmanagerに継承する形でメソッドを追加していた。
追加するメソッドはbooleanfieldにチェックが付いたものをフィルタリングするものだった。
なるほど データベースクエリの操作に関係しているメソッドだからmanagerを継承するのかと納得した。
またclass 定義にobjects =... と加えるのもデータベースに関連するからかと納得。

class についてちょっと整理する

models.pyにでclassを設定する

目的はデータベースを作るために行われる。
具体的にはテーブルのカラムを定めること。
そしてデータが入れられればデータベースとなる。

models.py

class Blog(models.Model):
    title = models.CharField(max_length=30)
    content = models.TextField()
    datetime = models.DateTimeField(auto_now=True)

クラス以下に書かれた変数がテーブルのカラムとなる。models.Field...の記述はフィールドにデータの性質を決めたり、入力の制限を決める。


データの入力の仕方
shellを使って入力する方法(python manage.py shell で可能)
adminから入力する方法(admin.pyにてadmin.site.register(クラス)を設定する)
入力フォーム、ページを作って編集する場合


shell で入力する場合は
create(**kwargs)メソッドを使う場合

obj = Blog.objects.create(title="Buen dia" ,content= "hoy hace mucho frio pero ..." )


class内のdefについて

その他関連記事

class内のdefについて

pythonについて全然理解していなかった。
関数?メソッド?全然区別がつかないとpythonを始めた頃はわからなかった。
9. クラス — Python 3.6.5 ドキュメント


クラスメソッドについて

少しだけわかったので記録する。
class内にdef で定義することがある。
この場合のdefはメソッドと言われる。
メッソドはクラスのインスタンスに対して使う。

class Hoge()
    def test1(self)
        return print("success")

def test1(self) を使い方は
a= Hoge() でクラスのインスタンスを作り、
a.test1() とすれば使える。
そしてこのHOGEは他のクラスの実体(インスタンス)には使えない。他のクラスの実体に使えないことをもってメソッドと称する。


今疑問なのはなぜメソッドとして使いたいのかってこと。
別に関数として定義しておけばいいんじゃないかって思うんだけど、、、

メソッドを使うときはインポートするときメソッドはインポートしなくて良い?ここが便利?

==とis の違い

>>> list1=[1,2,3,4,5]
>>> print(list1)
[1, 2, 3, 4, 5]
>>> print(id(list1))
4336674504
>>> list2=[1,2,3,4,5]
>>> print(id(list2))
4336702792
>>> list1==list2
True
>>> list1 is list2
False

==の場合内容が同じかどうかで判断する。
is の場合オブジェクトのidが同じかどうかで判断する。

セッションについてのメモ

色々なコードが一体何を表すのか分かっていないので調べたものはメモとして残す。

views.pyにて  ページに接続するたびにat以降が変わる

print(request.session)

<django.contrib.sessions.backends.db.SessionStore object at 0x10dc0aa90>
print(request.session.id)

AttributeError: 'SessionStore' object has no attribute 'id'

セッションのプロパティ確認方法(重要)

print(request.session.keys())
#表示された単語をrequest.session.***とつなげると辞書型データの値(バリュー)を得られる。

print(request.session.items())
#返されるデータはキーとバリューのセットで確認できる。

adminにログインした状態

print(request.session.session_key)

tz6gfiyhe84yy5ygb8j6avq4dsylres9

adminからログアウトした状態

print(request.session.session_key)

None

adminに再ログインすると 内容が変わった

print(request.session.session_key)

6z9a3oamusmjbzi4ivf42luqlujkuckz

request.userもターミナルにプリントすると

print(request.user)

Gustavo