2019/04/02

Djangoの国際化のmakemessagesでワイルドカードを使う方法

Djangoの国際化のmakemessagesでワイルドカードを使う方法.

Djangoサイトを国際化(多言語対応)するときに打つコマンド,makemessages でワイルドカードを使ってディレクトリを除外したりしたいとき,以下のようにすればOK.

makemessages -l en --ignore venv\*

または,

makemessages -l en --ignore "venv*"

上記の例では,venvで始まるディレクトリを無視している.

2019/03/30

Djangoで自前のformでデフォルトのパスワードvalidationをする方法.

Djangoで自前のformでデフォルトのパスワードvalidationをする方法.

訳あって,Userモデルを拡張したモデル(UserPrivate)に対して,ModelFormではなく自前のformでユーザの追加をしたくなった.
普通にformを作ってみると,デフォルトのパスワードvalidationが有効にならない.

下記のようにすることで,settingsのAUTH_PASSWORD_VALIDATORSに登録されたvalidatoionを実行してくれる.
usernameとpasswordしか入力させないフォームなので,self.instance.usernameしか代入していないが,firstnameとかemailとかも場合によっては必要になる.

本当はもっとうまい方法がありそうなものだけど,よくわからん.
知っている人がいたら教えてほしい.



from django.contrib.auth.password_validation import validate_password


class UserPrivateAddForm(forms.ModelForm):
    """アカウント追加フォーム"""
    username = forms.CharField(
        label='ユーザID',
        required=True,
    )
    password = forms.CharField(
        label='パスワード',
        widget=forms.PasswordInput,
        help_text='パスワードを入力してください.'
    )
   
    def clean_password(self):
        # パスワードのvalidation時に username と似た値を禁止するUserAttributeSimilarityValidatorを機能させるためにusernameを代入
        password = self.cleaned_data.get('password')
        self.instance.username = self.cleaned_data.get('username')  # usernameを代入
        validate_password(
            self.cleaned_data['password'],
            self.instance  # ここでusernameの入ったインスタンスを渡す必要がある
        )  # デフォルトのパスワードvalidation
        return password
   
    def save(self, commit=True):
        user_private = super().save(commit=False)
        user_private.set_password(self.cleaned_data["password"])
        if commit:
            user_private.save()
        return user_private
   
    class Meta:
        model = UserPrivate
        fields = [
            'username',
            'password',
        ]

2019/02/06

IEICEの研究会テンプレートで¥refコマンドに無駄なドットがつく問題の解決法

電子情報通信学会の研究会のLaTeXテンプレートで,refコマンドを使うと,「第2.章」のようにドットが入ってしまう問題を修正する方法.
普通のクラスファイルなら,¥usepackage{secdot}を使えば済むが,IEICEの場合は以下のようにする必要がある.

ieicej.clsの中の

\renewcommand{\thesection}{\@arabic\c@section.}
\renewcommand{\thesubsection}{\thesection\,\@arabic\c@subsection}

となっている部分を書き換え,ドットの位置を以下のようにする.

\renewcommand{\thesection}{\@arabic\c@section}
\renewcommand{\thesubsection}{\thesection.\,\@arabic\c@subsection}

さらに,プリアンブルに ¥usepackage{secdot} を書き加えればOK.

2019/01/15

PyCharmでPYTHONPATHを追加して独自モジュールを追加する方法

pythonでは上位のディレクトリに位置するモジュールを相対パスでimportできない.
別のところにおいてある独自モジュールを追加するためには,PYTHONPATHを追加する必要がある.
ターミナルでやるなら,exportを打つだけだが,IDEだとどうするのかいいのかわからなかったので調べた.

venvのbin/activateにexportを書く方法もあるが,動きはするものの,これだとPyCharm側でコードの警告が消えない.

PyCharm側でPYTHONPATHを追加すれば,警告は出ない.
方法は以下の通り.

Preferences => Project Interpreter => [歯車マーク] => Show all => [ディレクトリ階層マーク] => [プラスマーク]
と進んでパスを追加.

2018/10/24

pip (pip-18.1) を一括アップデートする方法

以下のサイトの方法などを試したが,そのままではうまくいかなかったので修正した.
https://qiita.com/Klein/items/a3110d20532ba9f9057b

修正したコマンドは以下の通り.

pip list -o | grep -v -e Package -e --- | awk '{print $1}' | xargs pip install -U pip


pip list -oで出てくるフォーマットが以下のようなものなので,最初の2行をgrepでパスしているだけ.

Package           Version   Latest     Type 
----------------- --------- ---------- -----
beautifulsoup4    4.6.0     4.6.3      wheel
...

2018/09/30

GCPのdebian上でseleniumのheadless firefoxを試みる

GCPのdebian上でseleniumのheadless firefoxを試みる

結論を言いますとうまくいきませんでした.
手元のMac上なら動くが,GCP上ではうまく行かず.


以下,やったことの記録.

以下のサイトに習い,geckodriveをインストール.
https://a-zumi.net/selenium-ubuntu-geckodriver/
https://github.com/mozilla/geckodriver/releases


firefoxをインストール.
sudo apt-get install firefox-esr

他にも,mozillaのリポジトリを追加して最新版を追加したり,debファイルを引っ張ってきて,旧版をインストールしたりしたが,結果的にはあまり意味なかった.

python3で以下のように実行.

from selenium import webdriver
from selenium.webdriver.firefox.options import Options
options = Options()
options.add_argument('-headless')
driver = webdriver.Firefox(firefox_options=options)


次のようなエラーが出る.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/bitnami/python/lib/python3.6/site-packages/selenium/webdriver/firefox/webdriver.py", line 170, in __init__
    keep_alive=True)
  File "/opt/bitnami/python/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 156, in __init__
    self.start_session(capabilities, browser_profile)
  File "/opt/bitnami/python/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 251, in start_session
    response = self.execute(Command.NEW_SESSION, parameters)
  File "/opt/bitnami/python/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 320, in execute
    self.error_handler.check_response(response)
  File "/opt/bitnami/python/lib/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.SessionNotCreatedException: Message: Unable to find a matching set of capabilities


試行錯誤の上,capabilities の marionette を False にするとcapability のエラーが無くなった.


from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.firefox.options import Options
options = Options()
options.add_argument('-headless')
desiredcapabilities = DesiredCapabilities.FIREFOX.copy()
desiredcapabilities['marionette'] = False
driver = webdriver.Firefox(capabilities=desiredcapabilities, firefox_options=options)


しかし,まだ以下のようなエラーが出る.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/bitnami/python/lib/python3.6/site-packages/selenium/webdriver/firefox/webdriver.py", line 187, in __init__
    self.binary, timeout)
  File "/opt/bitnami/python/lib/python3.6/site-packages/selenium/webdriver/firefox/extension_connection.py", line 52, in __init__
    self.binary.launch_browser(self.profile, timeout=timeout)
  File "/opt/bitnami/python/lib/python3.6/site-packages/selenium/webdriver/firefox/firefox_binary.py", line 73, in launch_browser
    self._wait_until_connectable(timeout=timeout)
  File "/opt/bitnami/python/lib/python3.6/site-packages/selenium/webdriver/firefox/firefox_binary.py", line 104, in _wait_until_connectable
    "The browser appears to have exited "
selenium.common.exceptions.WebDriverException: Message: The browser appears to have exited before we could connect. If you specified a log_file in the FirefoxBinary constructor, check it for details.


以下のようにすると,geckodriverのログを出力できる.

from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
desiredcapabilities = DesiredCapabilities.FIREFOX.copy()
desiredcapabilities['marionette'] = False
binary = FirefoxBinary(log_file=open("geckodriver.log", "wb"))
binary.add_command_line_options('-headless')
driver = webdriver.Firefox(capabilities=desiredcapabilities, firefox_binary=binary)

ログを見ると,以下のような内容.

XPCOMGlueLoad error for file /usr/lib/firefox-esr/libmozgtk.so:
/usr/lib/x86_64-linux-gnu/libpangoft2-1.0.so.0: undefined symbol: FcConfigReference
Couldn't load XPCOM.

このエラーがどうしても解決できずに断念.
chromeに切り替えることにした.


2018/10/8 追記
Chromeに変えても同様の問題が発生し,散々色々やった挙げ句,解決せず途方に暮れた.
結局,vmをbitnamiのdjangostacでやっていたのが問題だったようで,vmをbitnamiを使わず新たに立ち上げ直してやってみたらすんなり行って,拍子抜けした.

2018/07/22

スフレパンケーキのレシピ

2人分4枚の分量

卵黄 2個
卵白 2個
砂糖 10g
強力粉 30g
ベーキングパウダー 2g
牛乳 30g


レシピ
1) 卵白と砂糖以外の材料を混ぜる.
2) 卵白と砂糖をかなり固めのメレンゲにする.
3) 1)に2)を少し混ぜて,混ぜたら全部混ぜる.
4) 弱火に蓋をして,焼く.