2020年12月28日 星期一

轉址怎麼設定

常常我們萬不得已需要轉址,讓某些處在網路限制區域的捧油,可以訪問我們的服務。

這個時候就相當麻煩,因為大多數的捧油,是把static資料夾,用collectstatic的方式,讓例如nginx或是apache來處理。這樣轉址只要另外設定轉址位置即可。

若是development環境,則是這樣設置:
假設我們轉址網址是
http://foo/bar/
STATIC_URL='/bar/static/'
MEDIA_URL='/bar/media/'
LOGIN_REDIRECT_URL='/bar/bar/'
LOGIN_URL='bar/login/'

然後記得URLs.py設定
path('bar/', include('mysite.urls'))
即可。

2020年12月2日 星期三

Pandas 容易踩的坑(持續更新)

最近都在弄這隻熊貓,發現其中的坑還不少,趕快紀錄下來,希望大家不要跟我一樣了。

1. Python針對list的append,是立刻發生的,而Pandas dataframe 的append不是。
In Python:
foo=[]
bar=1
foo.append(bar)
print(foo)
....[1]

In Pandas:
foo = pd.DataFrame([[1,2]], columns=['A','B'])
bar = pd.DataFrame([[2,2]], columns=['A','B'])
foo.append(bar)
print(foo)
...A. B
0 1 2

所以要記得把結果存起來才行
foo = pd.DataFrame([[1,2]], columns=['A','B'])
bar = pd.DataFrame([[2,2]], columns=['A','B'])
foo=foo.append(bar)
print(foo)
...A. B
0 1 2
1 2 2



2020年11月2日 星期一

Docker MySQL cheat list

先移到打算存備份檔案的資料夾裡面

再執行

docker cp <container id>:<path inside container, eg. /home/mysql.sql> .

這樣子就已經把備份檔存到本機目前所在資料夾裡面了。

之後,再把檔案移到新的容器裡

docker exec -i <container id> sh -c 'cat > <path you want to store the data, eg. /home/mysql.sql' < <備份檔案名, e.g. mysql. sql>

再來要進去那個容器

mysql -uroot -p <database name you backed up> < <path to the back up file, eg. /home/my first.sql >

登進去看看

mysql -uroot -p

>SHOW DATABASES; 

就完成囉!


2020年10月23日 星期五

csv的大坑

最近在弄產生csv檔給網頁使用者下載,才發現原來csv在處理中文的坑這麼多。趕快寫下來,不要重蹈覆轍了。

目標:讓使用者下載csv,且可以直接用Excel編輯,而不出現亂碼。


首先,把資料從資料庫裡面撈出來的時候,格式通常不會有問題。
所以只要
data = Data.objects.filter(name__icontains=Liang)
data_list = []
for i in data:
   data_list.append(i.name)
data_list.append(一些中文)
在寫入的時候,要使用utf_8_sig
with open('foo.csv', 'w', newline='', encoding='utf_8_sig') as f:
    writer  = csv.writer(f, delimiter=',')
    writer.writerow(data_list)

而提供檔案的時候:
def fake_view(request):
    file = open('foo.csv', 'r', encoding='utf-8')
    response = HttpResponse(file)
    response ['Content-Type'] ='application/octet-stream'
    response['Content-Disposition'] = 'attachment; filename="<The file name you want the user to have>" '
    return response 

2020年10月1日 星期四

Json常用指令

 當跟數據科學家合作案件,常常是用json傳遞資料。我們如果從資料庫拉資料出來,也常常是dictionary格式。

這裡梁哥整理一下平常常用的指令,作為一個cheat sheet。

假設出現json.decoder.JSONDecodeError:  Expecting property name enclosed in double quotes

你就需要將單引號換成雙引號,

str = str.replace("  \' ", "  \"  ")


如果需要轉成dictionary,就要搭配json.loads()

dictionary = json.loads(str)

2020年9月30日 星期三

2020年9月22日 星期二

Django formset用法

 這周在作表單,發現這實在是個大坑啊…花了很多時間在這個上面。


首先,推薦使用model formset_factory,因為方便不少。這個功能的特色是可以直接調用

formset = myformset(request.POST)

if formset.is_valid():

  formset.save()

  return redirect <the view u want to redirect>


那要怎麼用呢?

你可以選擇在forms.py裡面import 

from django.forms import modelformset_factory


class FakeForm(forms.ModelForm):

  class Meta:

    Model = Foo

    fields = ('list of the fields')


FakeFormset = modelformset_factory(Foo, FakeForm, extra=<how many u want>)


是不是很方便呢?


如果需要更高的可控性,只好使用一般的formset,缺點就是你得自己處理裡面的表單們。

formset = FooFormset(request.POST)

if formset.is_valid:

    for form in formset:

        field = form.cleaned_data.get('the input field name of the form')

<other fields>

instance = Foo.objects.create(field=field, ....)

instance.save()

return redirect ('<the  view you want to redirect the user>') 


這樣做就可以一次新增很多筆資料了。


2020年9月14日 星期一

Django 如何在url傳入參數

參考這篇:
stackoverflow.com/questions/25345392
通常我們連結都會寫成
{% url "<url name>"%}
但是當我們需要編輯一個項目時,往往需要傳入一個id
/<url >/<int:id>/
那這個要怎麼寫呢?
其實很簡單,就是
{% url '<url name>' id=item.id %}

文中還特別提到,當有複數個參數時,
{% url '<url name>' <param1>= sth.id <param2>=<sth else>.id%}

2020年8月31日 星期一

201911 慕尼黑機場T2漢莎非申根區貴賓室

梁哥拖了這麼久,終於要來寫去年的紀錄了。

這是疫情之前的紀錄,現在航空業爆炸慘,不曉得會不會有變。

貴賓室名稱: 慕尼黑機場第二航廈非申根區商務貴賓室
年月:2019.11
因為是慕尼黑,火腿和Prezel是必備的。大學裡面的食堂基本上也是常常吃這個。不過貴賓室自然好吃一點。(可能是心理作用??)

這就是這個貴賓室少有的熱食了。德國人本來就可以冷食吃整天。。。

近一點看,吃起來在歐洲來說還算不錯了。很多貴賓室根本就是餅乾吃到飽。

旁邊是沙拉吧,食材都算是新鮮。

麵包們,德國人很多種麵包,不過吃起來我覺得差不多。

咖啡在貴賓室自然是必備的。除了咖啡機之外,也可以去吧台點。不過德國不能拍到人,就不放圖了。

中間的那杯,就是去吧台點無乳糖版本的。

跟申根區內貴賓室,最大的差別就是有酒了。調酒都給他喝一輪。

當然也有滿坑滿谷的啤酒和軟性飲料。

飲料機來了。

最後來個覆盆莓奶酪和鬆餅結尾。完美,準備登機。

可惜現在暫時沒有機會去慕尼黑惹,希望疫情趕快結束啊~

這次的紀錄就到這囉…拜。

2020年8月20日 星期四

Django 出現OSError

 最近踩了Django的坑,覺得一定要記錄一下,不然太虧了。

出現的錯誤訊息是

OSError at <路徑>

[Error 5] inputoutput error 

這遇到的時候,真心讓人覺得頭疼。因為找不到相關的資訊。後來想起來,之前有網友提醒,一定要在上線前,把所有的print改掉。才發現原來是console被關到,產生出來的錯誤訊息。


意思是程式碼說要print,可是沒有console,我要怎麼print的意思


這時候,只有重新啟動程序一途了。而且要由nohup接管,就沒問題了。

PYTHONIOENCODING=utf-8 nohup python3 manage.py runserver 0:<port  you want to open> &


是不是很坑呢?

2020年8月13日 星期四

pip 的貼心小功能們

在把辛辛苦苦寫完的程式碼,部署到伺服器上時,最麻煩的,莫過於要裝許多的packages。不過,pip其實提供了很多很方便的語言喔!

首先在開發的電腦上面執行
pip freeze > requirements.txt
把產出的檔案,傳到伺服器上,再執行
pip install -r requirements.txt
就可以囉!
是不是很方便啊?

2020年8月3日 星期一

寫入excel的package:xlrd

由於咱們的使用者,期待能夠下載很多符合格式的文件,我們在遇到時間時,一定不能直接寫入,不然xlrd都會套用預設的通用格式,這樣就會出現一長串的數字。

要怎麼辦呢?其實python本身有個可以把日期變成文字的方法,叫做strftime

https://www.programiz.com/python-programming/datetime/strftime

例如:

from datetime import datetime

a = datetime.now()
a.strftime(%c)

即可產出我們習慣的文字格式時間喲。  敬請多加利用。

2020年7月30日 星期四

使用pandas去除資料中的缺失值

當我們要開始作資料分析,一定會遇到碰上有缺失資料的狀況,這個時候,我們就需要用pandas來把包含缺失值的數據刪除。
假設我們現在讀入了一個dataframe df,我們先把空格填入nan
df['<column name A>', '<column name B>'].replace('', np.nan, inplace=True)
 再來就是把是空格的欄位去掉。
df_new = df.dropna(inplace=True)
重設index,(這是為了要走for loop的時候不會出錯,如果只是資料分析其實可以略過)
df_new.reset_index(drop=True, inplace=True)

2020年7月21日 星期二

Chart.js產生帶有百分比的圖表

雖然amChart的圖表真的好看,但是開源的Chart.js有一個無人能擋的功能,就是可以直接右鍵下載。這個真的強。

但是也有美中不足的地方,像是要呈現出百分比,就需要額外的功夫了。

強者網友針對chart.js 2.0之後的版本,寫了code,趕緊來學習下。

https://stackoverflow.com/questions/37257034/chart-js-2-0-doughnut-tooltip-percentages

這則一定趕快存起來,之後絕對用得到。

2020年7月13日 星期一

使用django 產出amCharts.js 所需要的資料格式

最近在趕案子,在前輩的推薦之下,打算拋棄Chart.js 改投向amChart.js。

原因是當div空間不夠時,Chart.js的長條圖例文字會模糊不清。

不過這兩個套件要求的格式完全不同。

我們來看看amChart.js官方網站的長條圖示例。

<!-- Styles --> <style> #chartdiv { width: 100%; height: 500px; } </style> <!-- Resources --> <script src="https://www.amcharts.com/lib/4/core.js"></script> <script src="https://www.amcharts.com/lib/4/charts.js"></script> <script src="https://www.amcharts.com/lib/4/themes/animated.js"></script> <!-- Chart code --> <script> am4core.ready(function() { // Themes begin am4core.useTheme(am4themes_animated); // Themes end // Create chart instance var chart = am4core.create("chartdiv", am4charts.XYChart); // Add data chart.data = [{ "country": "USA", "visits": 2025 }, { "country": "China", "visits": 1882 }, { "country": "Japan", "visits": 1809 }, { "country": "Germany", "visits": 1322 }, { "country": "UK", "visits": 1122 }, { "country": "France", "visits": 1114 }, { "country": "India", "visits": 984 }, { "country": "Spain", "visits": 711 }, { "country": "Netherlands", "visits": 665 }, { "country": "Russia", "visits": 580 }, { "country": "South Korea", "visits": 443 }, { "country": "Canada", "visits": 441 }, { "country": "Brazil", "visits": 395 }]; // Create axes var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis()); categoryAxis.dataFields.category = "country"; categoryAxis.renderer.grid.template.location = 0; categoryAxis.renderer.minGridDistance = 30; categoryAxis.renderer.labels.template.adapter.add("dy", function(dy, target) { if (target.dataItem && target.dataItem.index & 2 == 2) { return dy + 25; } return dy; }); var valueAxis = chart.yAxes.push(new am4charts.ValueAxis()); // Create series var series = chart.series.push(new am4charts.ColumnSeries()); series.dataFields.valueY = "visits"; series.dataFields.categoryX = "country"; series.name = "Visits"; series.columns.template.tooltipText = "{categoryX}: [bold]{valueY}[/]"; series.columns.template.fillOpacity = .8; var columnTemplate = series.columns.template; columnTemplate.strokeWidth = 2; columnTemplate.strokeOpacity = 1; }); // end am4core.ready() </script> <!-- HTML --> <div id="chartdiv"></div>


Note: Above is the demo code of AmCharts.js

Original site: https://www.amcharts.com/demos/simple-column-chart/

不難發現對Django來說,需要從DB裡面query出所需的Queryset,再轉換成這個套件所需要的格式,需要花上一些時間。

不過確實是好物。

下次再跟大家分享這個部分。

先這樣了,拜。


2020年7月11日 星期六

Django針對欄位計算百分比

https://stackoverflow.com/questions/19286834/django-calculate-percentage-based-on-object-count

以上是原文出處。

基本上,這個回答的重點是在儲存問卷相關值時,其實應該儲存成不同的model class。

<model name>.objects.values('<group by 欄位名稱>').annotate(<計算出來欄位名稱>=Count('id')).order_by()

*SQL裡面你可以group by很多欄位,這裡也可以,例如:Book.objects.values('name', 'code').annotate(count=Count('id')).order_by

這樣會預設按照query結果的第一個欄位排序,例如:name, 而不是計算出來欄位名稱

2020年7月7日 星期二

Django Cheat Sheet

Recently, I came up with the deployment with Django.

Since I have got in the age that needs more record than my memory.

I'll just write them down here.

# create the directory
mkdir <project name>
cd <project name>
# In windows env, initiate virtual env.

python -m venv my_venv
my_venv\Scripts\activate

# Then install django

~/Liang$ pip install "django==3.0.4"

# Create proj folder

(my_venv) ~/Liang$ django-admin startproject mysite

cd mysite

# Create an app. eg.Login, Shopping cart.

(my_venv) ~/Liang/mysite$ python manage.py startapp <app_name>

In mysite/settings.py, add '<app_name>' in installed apps.

Then everything is done.