---
# System prepended metadata

title: 筆記/雜記-Django
tags: [Django, views.py, request, 雜記, form]

---

&emsp;&emsp;最近都在前、後端交錯地處理事項，思緒很難集中跟延續，新環境可能也有關係。
&emsp;&emsp;希望習慣新步調跟新方式之後，可以有多的時間處理資料結構、演算法跟設計模式。


---

&emsp;&emsp;url(/users/me)一直多了一段如果user未驗證，就會導出Django的rest_framework畫面(訪客權限)，花了大概四個半小時查驗／google，但也只知道問題「應該」落在djoser上。因為project的url沒有給出/users/me這段，但因為有引用djoser的樣子(?)。最後是被需求拉了一把: 
:::info
要直接在首頁就先要求登入權限，
所以直接封掉了在首頁具有訪客權限的可能。
:::
---
&emsp;&emsp;原本都是用url上的user_id當作動態參數(?)，作為撈current_user的依據，但意外地知道(已知用火)登入時所輸入的資料也可以抓來用(反正都已經驗證了，沒驗證的進不到下一關)，
```
@login_required()
def request_form(request):
    (略)
    if request.method == "POST":
        form = request_form(request.POST)
        if form.is_valid():
            instance = form.save(commit=False) # 來獲取尚未儲存到資料庫的表單物件。
            instance.applicant_id = applicant_id  # 設定 applicant_id 的值
            (略)
            return render(request, "registration/logout.html")
    (略)
```

&emsp;&emsp;只是這個def好像可以改寫成class，看起來就會比較順眼(?)~~而且還有個不曉得原因的bug未解決:~~ 
::: info
&emsp;&emsp;變更密碼的畫面一直導去rest_framework的預設畫面，而不是寫好的template，~~只好暫時先改Django的內容了~~(切忌)。
:::info
--後記
&emsp;&emsp;原來是我沒把template放進與app同名的子資料夾內所導致，放進去後就沒這個問題了。
:::
:::
---更新頁面---2023/07/29

&emsp;&emsp;在做新接的專案時，總讓我覺得漏了什麼，才趁著颱風假把課程撈出來再看一次，結果發現少了序列化(serialization)這段:

:::info
&emsp;&emsp;Serializer=>Converts a model instance to a dictionary.
&emsp;&emsp;e.q. a product object to Python dictionary.
:::


&emsp;&emsp;在django中，基本上應是把物件轉換成Python可以取用的格式。所以在JSON與字典(dict)中，互相轉換(serialization, deserialization)。

:::info
&emsp;&emsp;會特別強調「在django中」是因為serialization一詞好像在電腦科學中，包含但不限於此意的樣子
:::

------------------

```python=
# POST/products
    {
        'title':'cell'
        'price':'31.46'
    }
```
&emsp;&emsp;多了序列化的功能，當有request送到端點(endpoint)，其body應該會包含一物件。
&emsp;&emsp;在伺服器端就必須讀取其request的body，並進一步反序列化(deserialize)。最後將其結果儲存在資料庫。

&emsp;&emsp;序列化的同時，可以賦予要給的型態，好比說:
&emsp;&emsp;1. 附有hyperlinker，可以藉由django的ORM(Object Relational Mapping)篩選;
&emsp;&emsp;2. 直接賦值成另一個serializer，就會一併帶回另一個serializer所有序列化後的屬性;
&emsp;&emsp;3. 帶主鍵(Primary Key)。(一時忘了會一併帶回什麼，待補。)

* [Serializer](https://www.django-rest-framework.org/api-guide/fields/#serializer-fields)沒有text的欄位(TextField)，需要用CharField



-------------------

&emsp;&emsp;建立一個新功能通常會經歷的旅程:
:::info
Create Model--> Create Serializer--> Create View--> Register a route
:::
&emsp;&emsp;

--以下2024-01-10更新
# Celery
## 系統
:::info 

Windows 10: redis( as tasker), Django, celery
Linux: redis( as broker), eventlet

:::
:::warning
貌似Celery仍不支援Windows，所以Celery可以收到task，但無法傳到broker。
:::
在windows端:
> pipenv install eventlet
> celery -A myapp.celeryapp worker --loglevel=info -P eventlet

但celery beat 可以正常使用的樣子。


:::info
Available Fields

**task**
The name of the task to execute.
Task names are described in the Names section of the User Guide. Note that this is not the import path of the task, even though the default naming pattern is built like it is.

    @shared_task(name="example_name")
    可以指定名稱，並賦予在task對應的值=>
    {
    'task':'example_name'
    }


**schedule**

The frequency of execution.

This can be the number of seconds as an integer, a timedelta, or a crontab. You can also define your own custom schedule types, by extending the interface of schedule.

**args**
Positional arguments (list or tuple).

**kwargs**
Keyword arguments (dict).

**options**
Execution options (dict).

This can be any argument supported by apply_async() – exchange, routing_key, expires, and so on.

**relative**
If relative is true timedelta schedules are scheduled “by the clock.” This means the frequency is rounded to the nearest second, minute, hour or day depending on the period of the timedelta.

By default relative is false, the frequency isn’t rounded and will be relative to the time when celery beat was started.
:::

--以上2024-01-10更新


--以下2024-01-22更新
# 在Ubuntu上執行


## 在Linux中:
### @ /etc/systemd/system/celery.service # celery的常駐設定檔位置
:::info
[Unit]
Description=Celery Service
After=network.target

[Service]
User=user # Linux上的使用者名稱
Group=group # Linux上使用者的群組名稱
WorkingDirectory=/path/to/project # Django的專案目錄位置
EnvironmentFile=/path/to/.env #.env(環境變數)的檔案位置
ExecStart=celery -A app.name worker --loglevel=info # 於本機端使用的celery指令，於這行ExecStart=後面使用。 若有使用pipenv，其celery的位置要換成which celery所帶出的位置。

[Install]
WantedBy=multi-user.target

:::

### @ /etc/default/celeryd # celery的設定檔位置
:::info
CELERYD_NODES="worker" #celery的型態
CELERY_BIN="path" # celery的路徑，有使用pipenv的話，要用which celery找路徑
CELERY_APP="app" # worker的名稱
CELERYD_CHDIR="django_project_path" #django專案的路徑
CELERYD_OPTS="--time-limit=300 --concurrency=8" #額外參數，待確認這些是什麼
#CELERYD_LOG_LEVEL="DEBUG"
CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
CELERYD_PID_FILE="/var/run/celery/%n.pid"
CELERYD_USER="user" # Linux上的使用者名稱
CELERYD_GROUP="group" # Linux上使用者的群組名稱
CELERY_CREATE_DIRS=1
:::

#### 問題:
於 /etc/init.d 目錄底下放置腳本(script)的話，是不是每次重開機就會一併執行的意思?

<br></br>
##### key words: .service / celeryd / daemon / init.d
--以上2024-01-22更新

--以下2024-01-25更新
--以上2024-01-25更新