昨天已經新增了子頁面,之前是直接將照片嵌入在網頁中,並沒有考慮到店家與照片的關聯,今天要在子頁面上面放上對應店家的圖片。
更新 Photo ORM
一間店會有很多照片,因此我們需要將 Place 跟 Photo 建立一對多的關係。
在Django ORM的設計中,可以在一個物件中嵌入 Foreign Key 建立一對多的關係。
程式碼
# food/model.py
class Photo(models.Model):
name = models.CharField(max_length=255)
file = models.ImageField(upload_to='photos')
place = models.ForeignKey(Place, help_text="The place that this photo come from.", on_delete=models.SET_NULL, null=True)
Q:餐廳若是關起來了,我上傳的照片會怎麼樣?
A:兩個資料有關聯時,其中一筆資料(舉例餐廳)被刪除時常見有兩種做法。
中間有一個參數 on_delete=models.SET_NULL 就是表示 Place 被刪除時,不會刪除此Photo,只會設定為Null
https://www.delftstack.com/zh-tw/howto/django/django-setup-one-to-many-relationship/
https://docs.djangoproject.com/en/3.2/topics/db/examples/many_to_one/
修改完一樣要記得 makemigrations 和 migrate
python manage.py makemigrations
python manage.py migrate
將此店家的所有照片傳至模板
有兩種方法可以達成這個任務
直接在Photo 資料表中,找出屬於這一間餐廳的照片,使用filter()
這個過濾器,裡面可以直接使用place
這個參數 。
photo_list = Photo.objects.filter(place = place).all()
從餐廳的角度去搜尋,找出這間餐廳的所有照片,
因為Place 和 Photo 有關係,因此Django會自動幫Place產生photo_set這個變數,代表的就是這家餐廳的所有照片。
place.photo_set.all()
兩者的結果是一致的,只是思考思路和語法有所不同。
def place_introduction(request, place_id: int):
place = Place.objects.get(id=place_id)
# 方法一
# photo_list = Photo.objects.filter(place = place).all()
# 方法二
photo_list = place.photo_set.all()
return render(
request,
'food/place_introduction.html',
{'store': place,
'photo_list':photo_list,
},
)
integrate data
最後我們執行runserver
進入/admin
,將照片上傳到資料庫
會發現在place的地方成為了選單,內容是之前新增的店家資料
台南不需要米其林
- 專案程式碼
- 專案文件與鐵人賽文章
- 參賽團隊 台南巷弄美食獵人