###### tags: `django` # django入門(七) — 簡單範例(5)-Django ORM操作 ## IT邦連結(需使用電腦版瀏覽器):[點我前往](https://ithelp.ithome.com.tw/users/20145754/articles) 全部文章: [django入門(一) — 介紹與設定開發環境](https://hackmd.io/@aroncode/SkVeqBO2K) [django入門(二) — 建立資料庫與專案](https://hackmd.io/@aroncode/rkqgL_unY) [django入門(三) — 簡單範例(1)-建立app](https://hackmd.io/@aroncode/H1qirFdhF) [django入門(四) — 簡單範例(2)-範本與範本繼承](https://hackmd.io/@aroncode/rkFuiwKnY) [django入門(五) — 簡單範例(3)-靜態檔](https://hackmd.io/@aroncode/ByL4dFO2Y) [django入門(六) — 資料模型與填充程式](https://hackmd.io/@aroncode/BJot2iRnF) [django入門(七) — Django ORM操作](https://hackmd.io/@aroncode/SJec_hA3Y) ## Django ORM介紹 一般而言,我們要存取資料庫需要透過SQL語法,但在django則是使用ORM技術來存取資料庫, django提供新增、刪除、修改、搜尋的方法給開發者,語法簡單且可防止SQL injection。 物件關聯對映(Object-relational mapping, ORM),是一種程式設計技術,用於實現物件導向程式語言裡不同類型系統的資料之間的轉換。從效果上說,它其實是建立了一個可在程式語言裡使用的「虛擬物件資料庫」。如今已有很多免費和付費的ORM產品,而有些程式設計師更傾向於建立自己的ORM工具。 參考資料:[維基百科-ORM](https://zh.wikipedia.org/wiki/%E5%AF%B9%E8%B1%A1%E5%85%B3%E7%B3%BB%E6%98%A0%E5%B0%84) ## 新增 首先我們先在stock/templates/stock下建立一個stockCreate.html stock/templates/stock/stockCreate.html ``` {% extends 'main/base.html' %} {% block heading %}股票-新增{% endblock %} {% block content %} <form class="inlineBlock" method="post" action="{% url 'stock:stockCreate' %}"> {% csrf_token %} <p>名稱:<input type="text" name="stockname" value="" required></p> <p>股價:<input type="text" name="stockprice" value="" required></p> <p>簡介:<input type="text" name="stockcontent" value="" required></p> <input class="btn" type="submit" value="新增"> </form> {% endblock %} ``` stock/views.py 加入套件與函式 ``` import套件: from django.contrib import messages from django.shortcuts import render, redirect <-新增這個 ``` ``` def stockCreate(request): stockCreatetemplate = 'stock/stockCreate.html' if request.method == 'GET': return render(request, stockCreatetemplate) stockname = request.POST.get('stockname') if stockname: stockname = stockname.strip() if not stockname: return redirect('stock/stockCreate') stockprice = request.POST.get('stockprice') if stockprice: stockprice = stockprice.strip() if not stockprice: return redirect('stock/stockCreate') stockcontent = request.POST.get('stockcontent') if stockcontent: stockconetnt = stockcontent.strip() if not stockcontent: return redirect('stock/stockCreate') Stock.objects.create(name=stockname, price=stockprice, content=stockcontent) messages.success(request, '新增成功!') return redirect('stock:stock') ``` stock/urls.py的urlpatterns加入以下路徑 ``` path('stockCreate/', views.stockCreate, name='stockCreate') ``` ## 刪除 stock/templates/stock/stock.html中的{% for stock in stocks %}區塊替換成以下 ``` {% for stock in stocks %} <div align="left"> <form style="display:inline" method="post" action="{% url 'stock:stockDelete' stock.id %}"> {% csrf_token %} <input class="btn" type="submit" value="刪除"> </form> <div> <h3>名稱:{{ stock.name }}</h3> <p>當前股價:{{ stock.price }}</p> <p>簡介:{{ stock.content }}<p> <hr> </div> </div> {% endfor %} ``` stock/views.py ``` 最上方既有的django.shortcuts再 import 一個 get_object_or_404 ``` ``` def stockDelete(request, stockId): ''' Delete a comment: 1. Get the comment to update and its article; redirect to 404 if not found 2. If it is a 'GET' request, return 3. If the comment's author is not the user, return 4. Delete the comment ''' stock = get_object_or_404(Stock, id=stockId) stock.delete() messages.success(request, '刪除成功!') return redirect('stock:stock') ``` stock/urls.py的urlpatterns加入以下路徑 ``` path('stockDelete/<int:stockId>/', views.stockDelete, name='stockDelete') ``` 這裡的int:stockId是用來傳遞參數的。 ## 搜尋 第一步於templates/stock 下建立一個stockSearch.html 這裡我們用範本標籤的寫法,因為有可能會有多個地方會用到搜尋這個功能,所以我們將搜尋表單獨立一個html,再透過{% include 'stock/stockSearch.html' %}放到我們需要用的地方。 stock/templates/stock/stock.html ``` ... <h2>{{ stock }}</h2> {% include 'stock/stockSearch.html' %} <-加到這裡 <div align="right"> ... ``` stock/views.py加入以下code ``` def stockSearch(request): searchTerm = request.GET.get('searchTerm') stocks = Stock.objects.filter(Q(name__icontains=searchTerm)| Q(price__icontains=searchTerm)| Q(content__icontains=searchTerm)) context = {'stock':'stock page','stocks':stocks, 'searchTerm':searchTerm} return render(request, 'stock/stock.html', context) ``` stock/urls.py的urlpatterns加入以下路徑 ``` path('stockSearch/', views.stockSearch, name='stockSearch') ``` ## 修改 stock/templates/stock 下建立stockUpdate.html stock/templates/stock/stockUpdate.html ``` {% extends 'main/base.html' %} {% block heading %}股票-修改{% endblock %} {% block content %} <form class="inlineBlock" method="post" action="{% url 'stock:stockUpdate' stock.id %}"> {% csrf_token %} <p>名稱:<input type="text" name="stockname" value="{{stock.name}}" required></p> <p>股價:<input type="text" name="stockprice" value="{{stock.price}}" required></p> <p>簡介:<input type="text" name="stockcontent" value="{{stock.content}}" required></p> <input class="btn" type="submit" value="修改"> </form> {% endblock %} ``` stock/views.py ``` def stockUpdate(request, stockId): stock = get_object_or_404(Stock, id=stockId) template = 'stock/stockUpdate.html' if request.method == 'GET': context={'stock':stock } return render(request, template,context) # POST stockname = request.POST.get('stockname') stockprice = request.POST.get('stockprice') stockcontent = request.POST.get('stockcontent') stock.name=stockname stock.price=stockprice stock.content=stockcontent stock.save() messages.success(request, '修改成功!') return redirect('stock:stock') ``` stock/urls.py的urlpatterns加入以下路徑 ``` path('stockUpdate/<int:stockId>/', views.stockUpdate, name='stockUpdate') ``` ## 補充語法(以Stock model為例) ### 新增 1.Stock.objects.create(...) 2. stock = Stock() stock.name="台積電" stock.price=670 .. stock.save() ### 搜尋 Stock.objects.all() Stock.objects.get(...) Stock.objects.filter(...) Stock.objects.exclude(...) Stock.objects.order_by(...) Stock.objects.filter(...).order_by(...) ### 刪除 stock = Stock.objects.get(...) stock.delete() ### 更新 stock = Stock.objects.get(...) stock.name="台積電" stock.price=670 .. stock.save()