出乎意料的簡單,原本還以為很麻煩的:django revert last migration – Stack Overflow
先執行 ./manage.py showmigrations my_app 列出所有的 migrations
然後執行 ./manage.py migrate my_app <0010_previous_migration>
這樣就可以 Revert 了。
Just thinking more…
出乎意料的簡單,原本還以為很麻煩的:django revert last migration – Stack Overflow
先執行 ./manage.py showmigrations my_app 列出所有的 migrations
然後執行 ./manage.py migrate my_app <0010_previous_migration>
這樣就可以 Revert 了。
邊看這篇 Celery – Best Practices 邊做的簡單摘錄與筆記。
CELERY_QUEUES = (
Queue('default', Exchange('default'), routing_key='default'),
Queue('for_task_A', Exchange('for_task_A'), routing_key='for_task_A'),
Queue('for_task_B', Exchange('for_task_B'), routing_key='for_task_B'),
)
CELERY_ROUTES = {
'my_taskA': {'queue': 'for_task_A', 'routing_key': 'for_task_A'},
'my_taskB': {'queue': 'for_task_B', 'routing_key': 'for_task_B'},
}
celery worker -E -l INFO -n workerA -Q for_task_A
celery worker -E -l INFO -n workerB -Q for_task_B
@app.task(bind=True, default_retry_delay=300, max_retries=5)
def my_task_A():
try:
print("doing stuff here...")
except SomeNetworkException as e:
print("maybe do some clenup here....")
self.retry(e) # Retry!
跟 Django 的整合可以參考 First steps with Django
裏面會要求你在 django app 的目錄下新增一個 celery.py,這裡有一行 app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) ,這行就是找到所有 tasks 的關鍵。找不到 task 的話,執行 python manage.py celeryd 時,不會有錯誤訊息,只在程式要執行這些 task 時印出錯務訊息,說找不到。
原始碼是在 celery/app/base.py 裡,大致就是依照 INSTALLED_APPS 列出的 package 去找 tasks,有的話就 import 進來。如果你的 celery task 沒有列在 INSTALLED_APPS 裡,或是函式不在 tasks 裡的話,可以再多加 app.autodiscover_tasks,例如 app.autodiscover_tasks([‘your_module’], related_name=’my_tasks’) ,這樣就可以引入使用了。
Ansible 有個 django_manage 模組,可以很方便的執行 django 裡的 manage.py,但是受限於 createsuperuser 的關係,並沒辦法在建立 superuser 的同時,一併設定密碼。
一般網路上的解決方法是自己寫個小 python 腳本 (可以看這篇 How to automate createsuperuser on django? ),丟給 shell 去執行。我是想到可以利用 manage.py 提供的 changepassword 並搭配 expect 來做,大致上是這樣子:
另外也做了避免重複建 superuser 的機制。
試用 python keyring 這個模組的一些紀錄:
同事問,為什麼用 model 建立 instance 以後,呼叫 save 沒有觸發 validate?
上網找了一下,大致有兩種方法:
事情沒有這樣結束,因為很好奇 Django 的作法,就去追 Code。
如果是走 is_valid() :
至此,ModelForm 的路徑就確定了。
來看看第二個方法,他是要求 Model 類別除了繼承 Django Model 之外,再繼承 ValidateModelMixin 這個自訂類別以覆寫 save() ,看看裏面的 save(),就只是多呼叫了 full_clean() 來檢查,也就是走上述步驟 4 以後的路線。
Django 官方網站不建議直接去呼叫 full_clean() 這件事,不過找了一下,也沒找到什麼更好的解法~
P.S.
會去追 code 主要是試著解決 Linux 下的 pip 不能用 IronPython 的問題,後來是沒解,但這是在去年年底時看的,我不知道現在是不是已經解決了。
pyenv install -l 這指令,大致做下面幾件事情:
因為 IronPython 2.7.5 才支援 pip,想要用 IronPython 2.7.5 (或更新的版本) ,可以這麼做:複製 .pyenv/plugins/python-build/share/python-build/ironpython-2.7.4 為 ironpython-2.7.5,把裏面的下載位址改為 https://github.com/IronLanguages/main/releases/download/ipy-2.7.5/IronPython-2.7.5.zip
這樣子,pyenv install -l 就會列出 ironpython-2.7.5,而且也可以下載安裝。
安裝 2.7.5 以後,用 pyenv shell ironpython-2.7.5 切換為 IronPython 2.7.5。
依照 2.7.5 的 release note 裡去執行 python -X:Frames -m ensurepip 時,卻出現以下的錯誤:
OSError: IronPython.Runtime.Exceptions.OSException: cannot load library at IronPython.Modules.CTypes.LoadLibrary (System.String library, Int32 mode) [0x00000] in <filename unknown>:0 at IronPython.Modules.CTypes.dlopen (System.String library, Int32 mode) [0x00000] in <filename unknown>:0 at Microsoft.Scripting.Interpreter.FuncCallInstruction`3[System.String,System.Int32,System.Object].Run (Microsoft.Scripting.Interpreter.InterpretedFrame frame) [0x00000] in <filename unknown>:0 at Microsoft.Scripting.Interpreter.Interpreter.Run (Microsoft.Scripting.Interpreter.InterpretedFrame frame) [0x00000] in <filename unknown>:0
會有這樣的錯誤,最主要是因為 ironpython-2.7.5/bin/Lib/ctypes/init.py 裡的 436~441 行,這裡是這樣寫的:
[python]
if _os.name in (“nt”, “ce”):
pythonapi = PyDLL(“python dll”, None, _sys.dllhandle)
elif _sys.platform == “cygwin”:
pythonapi = PyDLL(“libpython%d.%d.dll” % _sys.version_info[:2])
else:
pythonapi = PyDLL(None)
[/python]
這邊傳了 None 到 PyDLL,而 PyDLL 裡 (就 353 行) 的 _dlopen() 無法開啟 None ,才丟出這個 exception,有試著加程式處理掉這個 exception,但是,後續會因為這行
memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr) 而出現 SystemError: LocalAlloc 錯誤
結論,Linux 下,IronPython 還是沒辦法用 pip ,另外就是,我不知道現在修正了沒。
碰到這個歡樂的錯誤,其實已經碰過兩三次了,前面幾次都不了了之。
InsecurePlatformWarning: A true SSLContext object is not available.
這次是確實的找到方法可以不用改程式避掉的方法,方法很簡單,就是安裝 pyopenssl ndg-httpsclient pyasn1 這幾個模組,這幾個模組會自動將 SSL 相關的憑證注射到 urllib3 模組裡,下載時就不會有 InsecurePlatformWarning 的警告。
這方法是在 StackOverflow 的 python – InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately 看到解法的,感謝。
今天用 pyenv 安裝了 3.4.2,卻發現沒有 tkinter 模組,經過一番明查暗訪,終於知道原因。原因就是沒安裝 tk8.5-dev (我是用 12.04,14.04 要改為 tk8.6-dev),用 apt-get 裝上 tk8.5-dev,然後重新用 pyenv 安裝一次 3.4.2 就可以了:pyenv install 3.4.2 。
換言之,用 pyenv 安裝特定版本的 Python 時,會因為當前環境是否有安裝必要函式庫的 header 而影響能使用的模組,以後要特別注意。
前一陣子又在折騰 MonkeyRunner,意外發現有 easy 這個 module,順道研究了一下 ViewClient 。
easy 這個 module 是內建的,功用有點類似 jQuery,可以幫你直接找到目前畫面的某個元件,這樣就可以快速的在裏面填入文字或是按下按鈕等等。
這例子會啟動 Email ,然後將資料填入欄位後,寄出去。但實際上並不會寄出,而是存到草稿 (Draft) 裡,這是由於 Email 在寄送郵件的程式裡,有去判斷,假若是透過 MonkeyRunner 所觸發的事件,他就不寄送,而是存到草稿裡。
easy module 還有提供一些方便的函式,主要都是操作 UI 用的比較多。假若你有下載 Android 原始碼的話,這部份是在 sdk/monkeyrunner/src/com/android/monkeyrunner/easy 資料夾下面。
ViewClient 則是有人覺得不夠用,就另外自己開發了。一開始是配合 MonkeyRunner 才能使用,到了 3.0 以後,就可以不需要 MonkeyRunner,用 Python 搭配 Android SDK 就可以使用。 話是這麼說,但實際上,還是得視手機 Android 版本而定,總之使用 ViewClient 有看到錯誤訊息,就試著改用 2.3.25 的版本試試看吧。下面就是大致的用法:
ViewClient 在找元件的部份,有點亂,網站上文件也不太清楚,我追蹤原始碼,是一定要 dump ,才能找到。而且,沒辦法用 id 來找,只能用文字來找。看原始碼還有提到 UI Automator 這工具,但後來就沒詳究了。我後來沒有用 ViewClient ,所以…
小技巧,在找畫面上有哪些元件時,可以用 hierarchyviewer/hierarchyviewer1 這工具來看畫面佈局,這相當好用。
參考資料: