前面把三個 Model 全都完成囉~恭喜大家,現在應該都非常清楚 Model
和 CRUD
建置的流程了,現在!我們要在首頁,也就是 http://127.0.0.1:8000/online/
,補上一些資訊,讓使用者一進到這個頁面就可以看到所有的 Employer
、Store
、Product
。
先來整理一下等等會用到的一些頁面
<!-- 首頁 -->
http://127.0.0.1:8000/online/
request/response
的 views.py
檔案# online/views.py
def index(request):
num_employers = Employer.objects.all()
num_stores = Store.objects.all()
num_products = Product.objects.all()
context = {
"num_employers": num_employers,
"num_stores": num_stores,
"num_products": num_products,
}
return render(request, 'index.html', context=context)
# ...以下省略ㄋ
講解一下上面在幹嘛:
Employer
、Store
、Product
物件抓出來傳到一個變數上Ps. 應該會有人很好奇為什麼之前在其他頁面不用這樣寫變數傳遞,在這邊就要使用,原因就是我們之前使用的 generic
是 Django 提供的快速模板,我們只要設定 model = Employer
,就可以讓相對應的 templates
使用特定變數,像今天如果不是使用模板的話,就要像 index
這樣自己寫變數、傳遞變數
寫過 ROR 的人應該會對這種傳遞變數的方式很熟悉,因為 ROR 就是直接在方法這邊設定好要傳遞的資料,並且直接在 view 的地方使用
來修改這個頁面,用剛剛傳過來的變數 num_employers
跑迴圈,把 Employer 物件都印出來,並且用關聯寫法,從老闆 -> 商店 -> 產品,所有關聯全部印出來
<!-- online/templates/index.html -->
{% extends 'sidebar.html' %}
{% block content %}
<h1>這裡是線上商城的首頁</h1>
<hr>
<p>所有老闆: {{ num_employers }}</p>
<p>所有商店: {{ num_stores }}</p>
<p>所有產品: {{ num_products }}</p>
<hr>
{% for employer in num_employers %}
<ul>
<li><a href="{{ employer.get_absolute_url }}">id:{{ employer.id }}</a></li>
<li>姓:{{ employer.first_name }}</li>
<li>名:{{ employer.last_name }}</li>
<li>年齡:{{ employer.age }}</li>
<li>
老闆開的店:
{% for store in employer.store_set.all %}
<ul>
<li>{{ store.title }} : 有賣的產品 - {{ store.product_set.all | join:", " }}</li>
</ul>
{% endfor %}
</li>
</ul>
{% endfor %}
{% endblock %}
看到這邊感覺突然很混亂,別擔心,先看一下目前的圖,再來一行一行解釋:
num_employers
、num_stores
、num_products
,的確是傳過來了num_employers
,印出老闆所擁有的商店,再印出該商店有販賣哪些產品num_employers
抓出所有的老闆,並用迴圈印出來employer.store_set.all
抓出老闆所擁有的 Store
store.product_set.all
抓出該商店所販賣的產品,後面那一段 join 則是使用 python 的語法,可以把原先的陣列變成一個字串這樣應該可以理解到建立關聯的好處了,我只用 Employer 老闆
的資料,就可以抓出其他的商店和產品的所有資料,非常方便吧!
這邊在幫大家整理一次目前有用到的關聯寫法,不過在整理前,我們先再看一次 Model 設定:
# online/models.py
class Employer(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
age = models.PositiveIntegerField()
# ...省略
class Store(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
employer = models.ForeignKey(Employer, on_delete=models.SET_NULL, null=True)
# ...省略
class Product(models.Model):
title = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
store = models.ManyToManyField(Store)
# ...省略
看完 Model 整理一下目前有用到的關聯:
看完上面的 Model 設定和目前我們所使用的關聯,應該會發現有個共通的特性,就是假設今天把 employer 和 store
建立關聯, 而你的關聯是建立在 Store
,因為你的 Store
欄位裡面會有 Employer ID
,所以你用 Store
查 Employer
的話只要直接 store.employer
就好,但是反過來查,也就是用 Employer
查 Store
,你就需要使用 _set
這個方法,以這個為例就是 employer.store_set.all
。
Ps. 你也可以在 Store 和 Product 的關聯找到這個關係喔~
今天學到哪些東西呢?
最後附上 Github: https://github.com/eagle0526/Django-store