十一、项目实战一
項目實戰一
需求
以 前后端不分離的方式實現學生的增刪改查操作
學生列表功能
接口設計
url:/students/
請求方法:get
參數:
- 格式:查詢參數
| page | int | 否 | 頁碼,默認為1 |
| size | init | 否 | 每頁數據條數默認為10 |
| name | str | 否 | 根據姓名過濾 |
| age | int | 否 | 根據年齡過濾 |
| sex | int | 否 | 根據性別過濾 |
| phone | str | 否 | 根據手機過濾 |
| channel_id | int | 否 | 根據渠道過濾 |
響應:html
代碼
視圖
import math from urllib.parse import urlencodedef student_list(request):"""學生列表視圖"""# 1. 獲取查詢參數query_params = {key: value for key, value in request.GET.items()}# 2. 獲取分頁參數page = int(query_params.pop('page', 1))size = int(query_params.pop('size', 10))# 3. 獲取查詢集queryset = Student.objects.all()for key, value in query_params.items():try:queryset = queryset.filter(**{key: value})except:pass# 4. 分頁處理# 數據總條數total_num = queryset.count()# 總頁數total_page = math.ceil(total_num/size)# 下一頁if page < total_page:query_params.update({'page': page+1, 'size': size})next_page_query_params = urlencode(query_params)else:next_page_query_params = None# 上一頁if page > 1:query_params.update({'page': page - 1, 'size': size})pre_page_query_params = urlencode(query_params)else:pre_page_query_params = None# 分頁過濾queryset = queryset[(page-1)*size:page*size]# 5. 渲染模板并返回響應return render(request, 'crm/student_list.html', context={'queryset': queryset,'pre_page': pre_page_query_params,'next_page': next_page_query_params,'page': page,'total_num': total_num,'total_page': total_page})路由
path('students/', views.student_list, name='student-list'),模板
<html lang="zh-CN"> <head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><!-- 上述3個meta標簽*必須*放在最前面,任何其他內容都*必須*跟隨其后! --><title>學生列表</title><!-- Bootstrap --><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous"><!-- HTML5 shim 和 Respond.js 是為了讓 IE8 支持 HTML5 元素和媒體查詢(media queries)功能 --><!-- 警告:通過 file:// 協議(就是直接將 html 頁面拖拽到瀏覽器中)訪問頁面時 Respond.js 不起作用 --><!--[if lt IE 9]><script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script><script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script><![endif]--> </head> <body> <div class="container"><h1>學生列表</h1><div style="width: 800px">{% if queryset %}<a class="btn btn-success" style="float: right" href="{% url 'student-create' %}">添加</a><table class="table table-hover table-bordered table-condensed"><thead><tr><th>序號</th><th>姓名</th><th>年齡</th><th>性別</th><th>電話</th><th>渠道</th><th>創建時間</th><th>操作</th></tr></thead><tbody>{% for obj in queryset %}<tr><td>{{ forloop.counter }}</td><td>{{ obj.name }}</td><td>{{ obj.age | default:"" }}</td><td>{% if obj.sex == 1 %}男{% else %}女{% endif %}</td><td>{{ obj.phone | default:"" }}</td><td>{% if obj.channel %}{{ obj.channel.title }}{% endif %}</td><td>{{ obj.c_time }}</td><td><a class="btn btn-primary" href="{% url 'student-update' obj.id %}">編輯</a><a class="btn btn-danger" href="{% url 'student-delete' obj.id %}">刪除</a></td></tr>{% endfor %}</tbody></table><nav aria-label="..."><ul class="pager"><li class="previous {% if not pre_page %}disabled{% endif %}"><ahref="{% if pre_page %}?{{ pre_page }}{% else %}#{% endif %}"><spanaria-hidden="true">←</span> 上一頁</a></li><li class="next {% if not next_page %}disabled{% endif %}"><ahref="{% if next_page %}?{{ next_page }}{% else %}#{% endif %}">下一頁 <span aria-hidden="true">→</span></a></li></ul></nav>{% else %}<p>查不到數據...</p>{% endif %}</div> </div><!-- jQuery (Bootstrap 的所有 JavaScript 插件都依賴 jQuery,所以必須放在前邊) --> {# <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script>#} <!-- 加載 Bootstrap 的所有 JavaScript 插件。你也可以根據需要只加載單個插件。 --> {# <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>#} </body> </html>訪問http://127.0.0.1/crm/students/效果圖如下:
學生添加功能
學生添加頁面
接口設計
url:/students/create/
請求方法:get
響應:html頁面
代碼
訪問http://127.0.0.1/crm/students/create/效果圖如下:
學生添加
接口設計
url:/students/create/
請求方法:post
參數:
- 格式:form
| name | str | 是 | 姓名 |
| age | int | 否 | 年齡 |
| sex | int | 否 | 性別 |
| phone | str | 否 | 手機 |
| channel_id | int | 否 | 渠道id |
響應:重定向到學生列表頁面
代碼
打開F12,鼠標移動到“添加”按鈕上面,左下角展示路由路徑是在原有的路徑下面緊跟aaa
?如果a標簽里href為以"/"開頭的,比如說“/aaa”那就直接從根路由后面緊跟你href的值,如下圖
大家看出區別來了嗎??
?那此時添加按鈕我可以直接寫成創建學生也就是學生詳情那個界面的路由嗎?當然可以,但不過這樣子寫就是硬編碼。
?我們應該用模板標簽
然后我們看渠道是下拉選擇框,那這個選擇項我們怎么獲取?肯定是從數據庫查了獲取對吧。此時思路就是這樣子:
1. 先去數據庫查有幾個渠道。
2. 查到之后渲染模板。
?
學生修改功能
學生修改頁面
接口設計
url:/students/update/pk/
請求方法:get
響應:html頁面
代碼
學生修改
接口設計
url:/students/update/pk/
請求方法:post
參數:
-
路徑參數
-
格式:form
| name | str | 否 | 姓名 |
| age | int | 否 | 年齡 |
| sex | int | 否 | 性別 |
| phone | str | 否 | 手機 |
| channel_id | int | 否 | 渠道id |
響應:重定向到學生列表頁面
代碼
同上
學生刪除功能
接口設計
url:/students/delete/pk/
請求方法:get
參數:
- 路徑參數
響應:重定向到學生列表頁面
代碼
總結
- 上一篇: 什么是大数据,大数据的特点
- 下一篇: root华为u8860