iT邦幫忙

2023 iThome 鐵人賽

DAY 22
0
自我挑戰組

Django 初學入門 - 從 ROR 的角度來學習 Django系列 第 22

DAY22 - 首頁 index.html 頁面設定

  • 分享至 

  • xImage
  •  

前面把三個 Model 全都完成囉~恭喜大家,現在應該都非常清楚 ModelCRUD 建置的流程了,現在!我們要在首頁,也就是 http://127.0.0.1:8000/online/,補上一些資訊,讓使用者一進到這個頁面就可以看到所有的 EmployerStoreProduct

連結

先來整理一下等等會用到的一些頁面

<!-- 首頁 -->
http://127.0.0.1:8000/online/

views.py

  1. 先到收發 request/responseviews.py 檔案
  2. 到我們一開始設定好 index 方法的地方改成以下資訊
# 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)

# ...以下省略ㄋ

講解一下上面在幹嘛:

  1. EmployerStoreProduct 物件抓出來傳到一個變數上
  2. 包在 context 裡面把變數傳給指定頁面,讓指定頁面可以使用該變數

Ps. 應該會有人很好奇為什麼之前在其他頁面不用這樣寫變數傳遞,在這邊就要使用,原因就是我們之前使用的 generic 是 Django 提供的快速模板,我們只要設定 model = Employer,就可以讓相對應的 templates 使用特定變數,像今天如果不是使用模板的話,就要像 index 這樣自己寫變數、傳遞變數


寫過 ROR 的人應該會對這種傳遞變數的方式很熟悉,因為 ROR 就是直接在方法這邊設定好要傳遞的資料,並且直接在 view 的地方使用


templates

來修改這個頁面,用剛剛傳過來的變數 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 %}

看到這邊感覺突然很混亂,別擔心,先看一下目前的圖,再來一行一行解釋:

https://ithelp.ithome.com.tw/upload/images/20231003/20162365RL8xPRnaTy.png

  1. 最上方的地方,可以看出我們剛剛在 views.py 設定的三個變數 num_employersnum_storesnum_products,的確是傳過來了
  2. 下面一大塊,我想做到的是,用老闆的變數 num_employers,印出老闆所擁有的商店,再印出該商店有販賣哪些產品
  3. 因此首先我們用 num_employers 抓出所有的老闆,並用迴圈印出來
  4. 再來用老闆和商店的關聯,用 employer.store_set.all 抓出老闆所擁有的 Store
  5. 最後用商店和產品的關聯,用 store.product_set.all 抓出該商店所販賣的產品,後面那一段 join 則是使用 python 的語法,可以把原先的陣列變成一個字串

這樣應該可以理解到建立關聯的好處了,我只用 Employer 老闆 的資料,就可以抓出其他的商店和產品的所有資料,非常方便吧!

關聯方法整理

這邊在幫大家整理一次目前有用到的關聯寫法,不過在整理前,我們先再看一次 Model 設定:

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 整理一下目前有用到的關聯:

  1. store.employer -> 用 Store 找到這間商店的老闆
  2. product.store.all -> 用 Product 找到這個產品販賣的商店
  3. employer.store_set.all -> 用 Employer 找到老闆所擁有的商店
  4. store.product_set.all -> 用 Store 找到商店所販賣的所有產品

看完上面的 Model 設定和目前我們所使用的關聯,應該會發現有個共通的特性,就是假設今天把 employer 和 store 建立關聯, 而你的關聯是建立在 Store,因為你的 Store 欄位裡面會有 Employer ID,所以你用 StoreEmployer 的話只要直接 store.employer 就好,但是反過來查,也就是用 EmployerStore,你就需要使用 _set 這個方法,以這個為例就是 employer.store_set.all

Ps. 你也可以在 Store 和 Product 的關聯找到這個關係喔~

總結

今天學到哪些東西呢?

  1. 首頁補完資訊 - 在 views.py 傳遞變數給 templates
  2. 關聯方法使用的詳細解析

最後附上 Github: https://github.com/eagle0526/Django-store


上一篇
DAY21 - Product CRUD 的 DELETE
下一篇
DAY23 - Django console 介紹
系列文
Django 初學入門 - 從 ROR 的角度來學習 Django30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言