Django 2で "does not appear to have any patterns in it" エラー

Django 2系で発生。

    raise ImproperlyConfigured(msg.format(name=self.urlconf_name))
django.core.exceptions.ImproperlyConfigured: The included URLconf '<module 'apps.aaaa.urls' from '/Users/aa/PycharmProjects/project1/apps/aaaa/urls.py'>' does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import.

urls.py

urlpatterns = (
    # www.example.com/path/info/
    url(r'^accounts/', views.api1, name="api1")
)

tuple ( ) でurlpatternsを作って、要素数が1個だと、このエラーが発生するっぽい。

listにすると解決。

urlpatterns = [
    # www.example.com/path/info/
    url(r'^accounts/', views.api1, name="api1")
]

要素の末尾に
url(r'^accounts/', views.api1, name="api1"),
, をつけても直る。

pyenvのアップグレードとpython 3.6.1のインストール

MacOSにPython3系の環境を構築する必要があったので、3系の新しいやつを入れた。

pyenvのアップグレード

インストール済みのPython環境を表示

pyenv versions

インストール可能なPython環境を表示

pyenv install -l

  3.5.3rc1
  3.6.0
  3.6-dev
  3.7-dev
  anaconda-1.4.0
  anaconda-1.5.0

3.6系の最新版がなかった。

repository - Why is python 3.6.1. not available in pyenv? - Stack Overflow

brew update 
brew upgrade pyenv

インストール可能なバージョンが増えた

pyenv install -l

  3.5.5
  3.5.6
  3.6.0
  3.6-dev
  3.6.1
  3.6.2
  3.6.3
  3.6.4
  3.6.5
  3.6.6
  3.6.7
  3.7.0
  3.7-dev
  3.7.1
  3.8-dev
  activepython-2.7.14
  activepython-3.5.4
  activepython-3.6.0
  anaconda-1.4.0
  anaconda-1.5.0

3.6系の最新は3.6.7だった。

3.6系インストール

pyenv install 3.6.7

エラー

~% pyenv install 3.6.7

python-build: use readline from homebrew
Downloading Python-3.6.7.tar.xz...
-> https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tar.xz
Installing Python-3.6.7...
python-build: use readline from homebrew
ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?

Please consult to the Wiki page to fix the problem.
https://github.com/pyenv/pyenv/wiki/Common-build-problems


BUILD FAILED (OS X 10.10.5 using python-build 20180424)

Inspect or clean up the working tree at /var/folders/1s/14vkt60n019bjctmy0rvg6cm0000gn/T/python-build.20181108122443.24403
Results logged to /var/folders/1s/14vkt60n019bjctmy0rvg6cm0000gn/T/python-build.20181108122443.24403.log

Last 10 log lines:
            install|*) ensurepip="" ;; \
        esac; \
         ./python.exe -E -m ensurepip \
            $ensurepip --root=/ ; \
    fi
Looking in links: /var/folders/1s/14vkt60n019bjctmy0rvg6cm0000gn/T/tmp8ebvuene
Collecting setuptools
Collecting pip
Installing collected packages: setuptools, pip
Successfully installed pip-10.0.1 setuptools-39.0.1

HighSierraにしてpyenvからpython入れようとしたら失敗した”The Python ssl extension was not compiled. Missing the OpenSSL lib?” - Qiita
https://github.com/pyenv/pyenv/wiki/Common-build-problems

以下のコマンドを再実行。

CFLAGS="-I$(brew --prefix openssl)/include" LDFLAGS="-L$(brew --prefix openssl)/lib" pyenv install 3.6.7

~% pyenv versions
でインストールされたことを確認。

その他

ndenvはanyenvとして入っていたけど、pyenvはbrewで入れたままになっているので、anyenvに統一したい。

anyenvのndenvで、vueコマンドが使えなかった

% mkdir example1
% cd example1
% cat .node-version  
v6.9.4
example1% npm install -g vue-cli 
インストール完了

example1% vue
zsh: command not found: vue

コマンドが見つからない

example1% npm install -g @vue/cli
インストール完了

example1% vue
zsh: command not found: vue

コマンドが見つからない

PATHを通す

export PATH=$PATH:~/.anyenv/envs/ndenv/versions/v6.9.4/bin/
example1% vue

You are using Node v6.9.4, but this version of vue-cli requires Node >=8.9.
Please upgrade your Node version.

エラー

export PATH=$PATH:~/.anyenv/envs/ndenv/versions/v6.9.4/lib/node_modules/vue-cli/bin
example1% vue

Usage: vue <command> [options]

Options:

  -V, --version  output the version number
  -h, --help     output usage information

Commands:

  init           generate a new project from a template
  list           list available official templates
  build          prototype a new project
  create         (for v3 warning only)
  help [cmd]     display help for [cmd]

動いた

vueプロジェクト作成

example1% vue init webpack app1-frontend-html

? Project name app1-frontend-html
? Project description A Vue.js project
? Author aaabbb <mail1@aaabbbbcccc.jp>
? Vue build standalone
? Install vue-router? No
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests Yes
? Pick a test runner jest
? Setup e2e tests with Nightwatch? Yes
? Should we run `npm install` for you after the project has been created? (recommended) npm

   vue-cli · Generated "app1-frontend-html".


# Installing project dependencies ...

ローカルサーバー起動

example1% npm run dev
npm ERR! Darwin 14.5.0

npm ERR! enoent ENOENT: no such file or directory, open '/Users/aaa/codes/vuejs/example1/package.json'
npm ERR! enoent This is most likely not a problem with npm itself
npm ERR! enoent and is related to npm not being able to find a file.

ローカルウェブサーバーが起動しなかった。

コマンドを実行する階層が違っていたのが原因だった。

example1/app1-frontend-html% npm run dev  

Pythonの可変長引数を別の関数にそのまま渡す

可変長引数に引数を追加して別の関数に渡す方法。

キーワード可変長引数の変数kwargs (dict型)に要素を足して、 test2(param1, **kwargs)
のようにアスタリスクを2個つけて渡すだけだった。

def test1(param1, **kwargs):
    print("----------")
    print("test1 func")
    print param1
    print kwargs
    kwargs["param4"] = "added in test1()"
    test2(param1, **kwargs)

def test2(param1, **kwargs):
    print("----------")
    print("test2 func")
    print param1
    print kwargs

test1("tes1", param2="test2", param3="test3")

実行結果

----------
test1 func
tes1
{'param3': 'test3', 'param2': 'test2'}
----------
test2 func
tes1
{'param4': 'added in test1()', 'param3': 'test3', 'param2': 'test2'}

英語での名称

**args は、 可変長引数
variable length argument

**kwargs は、 キーワード可変長引数
keyworded variable length argument
と呼ぶっぽい。 kwargs の kw は keywordの短縮だった。

キーワード可変長引数を変数に入れる

キーワード可変長引数も引数なのだから、変数に入っているべきなのではないかと思ったけど、
PyCharmのエディタでエラーになる。

def test1_2(param1, **kwargs):
    print("----------")
    print("test1_2 func")
    print param1
    print kwargs

    for key,val in kwargs.items():
        exec(key + '=val')
    print param2

PyCharmのエディタで Unresolved reference 'param2' というエラーになる。

実行はできる。

----------
test1_2 func
tes1
{'param3': 'tes3', 'param2': 'tes2'}
tes2

変数の名前が決まっているなら、関数定義に足せばいいっぽい。

def test1_2(param1, param2, **kwargs):
    print("----------")
    print("test1_2 func")
    print param1
    print kwargs

    for key,val in kwargs.items():
        exec(key + '=val')
    print param2

test1_2("tes1", param2="tes2", param3="tes3")

https://stackoverflow.com/questions/18090672/convert-dictionary-entries-into-variables-python

Django Middlewareのメンバー変数(クラス変数?)がリクエストをまたいで保持されていた

ウェブアプリは、1リクエストごとに別のプロセスが生成されて、変数は共有されないと思っていたけど、
Django Middlewareの変数は、リクエスト間で共有されているっぽい。
あとで仕組みを調べようと思う。

https://docs.djangoproject.com/en/1.9/topics/http/middleware/

https://docs.djangoproject.com/en/2.1/topics/http/middleware/

class SimpleMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

memo

class Middleware1(object):

    _count_test = 1

    def __init__(self):
        # One-time configuration and initialization.
        print "Middleware1: __init__()"

    def process_response(self, request, response):
        """
        viewを実行した後に呼びだされるフック。
        """
        print "Middleware1:" + str(self._count_test)
        self._count_test = self._count_test + 1
        return response

settings.py

MIDDLEWARE_CLASSES = (
  
  "apps.test1.middleware.Middleware1",

)

PyCharm WebServerコンソールログ

Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Middleware1: __init__()
Middleware1:1
[07/Sep/2018 15:29:27] "GET / HTTP/1.1" 200 1015
Middleware1:2
[07/Sep/2018 15:29:28] "GET /xxx HTTP/1.1" 200 182
Middleware1:3
[07/Sep/2018 15:29:28] "GET /xxx HTTP/1.1" 200 70
Middleware1:4
[07/Sep/2018 15:29:28] "GET /xxx HTTP/1.1" 200 571
Middleware1:5
[07/Sep/2018 15:29:28] "GET /xxx HTTP/1.1" 200 163
Middleware1:6
[07/Sep/2018 15:29:29] "GET /xxx HTTP/1.1" 200 2530
Middleware1:7
[07/Sep/2018 15:29:29] "GET /xxx HTTP/1.1" 200 85
Middleware1:8
[07/Sep/2018 15:29:29] "GET /xxx HTTP/1.1" 200 0
Middleware1:9
[07/Sep/2018 15:29:29] "GET /xxx HTTP/1.1" 200 581
[07/Sep/2018 15:29:29] "GET /xxx HTTP/1.1" 200 5016
Middleware1:10
Middleware1:11
[07/Sep/2018 15:29:29] "GET /xxx HTTP/1.1" 200 53882
[07/Sep/2018 15:29:33] "GET /xxx HTTP/1.1" 200 9004
Middleware1:12
[07/Sep/2018 15:29:33] "GET /xxx HTTP/1.1" 200 9004
Middleware1:13
Middleware1:14
[07/Sep/2018 15:29:33] "GET /xxx HTTP/1.1" 200 9004

MariaDBでタイムゾーンを設定しようとしたらエラーになった。

/etc/my.cnf

[mysqld]
default-time-zone='Asia/Tokyo'

/var/log/mariadb/mariadb.log

[ERROR] Fatal error: Illegal or unknown default time zone 'Asia/Tokyo'

MySQLでタイムゾーンの設定 - There's an echo in my head
この記事にあるコマンドを実行したらmariadbが起動した。

mysql_tzinfo_to_sql /usr/share/zoneinfo/ | mysql -u root -p mysql

Djangoのモデルデータをテスト用コードから呼び出した時のエラー

動作確認のために、普通のPythonスクリプトからDjango Modelを使おうとしたらエラーになった。

エラー1:

django.core.exceptions.ImproperlyConfigured: Requested setting CACHES, but settings are not configured. You must either define the environment variable  DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.  

PyCharmの設定で、Run Configurations > Environment variables に
name:DJANGO_SETTINGS_MODULE
value:AppName.settings
value:settings
を足して解決。

エラー2:

django.core.exceptions.AppRegistryNotReady: The translation infrastructure cannot be initialized before the apps registry is ready. Check that you don't make non-lazy gettext calls at import time.  

モデルのインポートの前にdjango.setup()で解決。
from apps.app1.models import Model1

django.setup()