django入门(七) — 简单范例(5)-Django ORM操作

Django ORM介绍

一般而言,我们要存取资料库需要透过SQL语法,但在django则是使用ORM技术来存取资料库,
django提供新增、删除、修改、搜寻的方法给开发者,语法简单且可防止SQL injection。

物件关联对映(Object-relational mapping, ORM),是一种程序设计技术,用於实现物件导向程序语言里不同类型系统的资料之间的转换。从效果上说,它其实是建立了一个可在程序语言里使用的「虚拟物件资料库」。如今已有很多免费和付费的ORM产品,而有些程序设计师更倾向於建立自己的ORM工具。
参考资料:维基百科-ORM

新增

首先我们先在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):
    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/stockSearch.html

<form action="{% url 'stock:stockSearch' %}">
  <input type="text" placeholder="输入关键字" name="searchTerm"  {% if searchTerm %}value="{{ searchTerm }}"{% endif %}>
  <input class="btn" type="submit" value="查询">
</form>

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)
        
    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为例)

搜寻

...为筛选条件
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()

新增

...为资料表各栏位资料
1.Stock.objects.create(...)
2.stock = Stock()
stock.name="台积电"
stock.price=670
..
stock.save()

更新

stock = Stock.objects.get(...)
stock.name="台积电"
stock.price=670
..
stock.save()

参考资料:django文件-Models and databases


<<:  Winx网站要转用wordpress

>>:  git不再支援帐号密码验证

[Day 18] 资料产品生命周期管理-自动决策

如同前面所说,资料模型需要运用到实际环境中才会发挥价值 Initiation 延续之前辅助决策的初始...

Day19 Combine 06 - Operators 类型介绍 : 过滤操作符

filter filter 只会让满足条件的值通过,filter接受一个闭包作为引数,该闭包返回一个...

什麽是功能分解?

功能分解对应於各种功能关系,如原始复杂业务功能的开发方式。它主要关注如何开发整体功能及其各个组件之间...

Android学习笔记16

因为如果把dialog写在viewmodel里面,之後在自动化测试的时候可能会出问题,所以在mvvm...

Material UI in React [Day4] Theme (自订主题 Palette & Typography)

继昨天 ThemeProvider 的部分今天来讲解一下 Material UI 的 Theme,大...