Django 網(wǎng)頁公共部分編寫
前言:目前還在學(xué)習(xí)中,這是第一個嘗試的項目,多有不足,感謝大家的觀看與批評。
目標(biāo):
一. 前端頁面
這次沒找到前輩的模板,自行編寫base.html和base.css
<!DOCTYPE html>
<html lang="zh-CN">
{% load static %}
<head>
<meta charset="UTF-8">
<title>用戶界面</title>
<link rel="stylesheet" type="text/css" href="{% static 'base/scripts/svg_img/iconfont.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'base/css/base.css' %}">
</head>
<body>
{# 上方基本信息展示 #}
<nav class="nav_top">
<div class="leftNav iconfont"> 刷票管理平臺</div>
<div class="rightSvg iconfont"></div>
<div class="rightNav">zcc</div>
</nav>
{# 下方主要內(nèi)容部分 #}
<div class="main_content">
<div class="mainDiv">
{# 左邊導(dǎo)航欄 #}
<div class="leftDiv">
<div class="iconfont"> 用戶信息</div>
<ul class="user_info" style="margin-bottom: 0">
<a href="#"><li>個人資料</li></a>
<a href="#"><li>我的交易</li></a>
</ul>
<div class="iconfont"> 平臺分類</div>
<ul class="plat_type">
<a href="#"><li>央視頻</li></a>
<a href="#"><li>B站完播</li></a>
<a href="#"><li>B站播放量(30%~50%完播)</li></a>
</ul>
</div>
{# 右側(cè)用戶操作內(nèi)容展示,這里是上方的小字導(dǎo)航欄和右側(cè)、下側(cè)的滑塊部分 #}
<div class="rightDiv">
<div class="infor">
</div>
<div class="information">
</div>
</div>
</div>
</div>
</body>
</html>
* {
margin: 0;
padding: 0;
}
/*頂部基本信息展示部分*/
.nav_top {
background-color: #2f72ab;
width: 100%;
height: 60px;
border-top-left-radius: 12px;
border-top-right-radius: 12px;
position: fixed;
}
/*左部導(dǎo)航欄*/
.leftNav {
float: left;
height: 20px;
padding-left: 40px;
padding-top: 20px;
font-family: Microsoft YaHei;
color: white;
}
/*右側(cè)用戶操作內(nèi)容部分*/
.rightNav {
float: right;
height: 20px;
padding-top: 20px;
font-family: Microsoft YaHei;
color: white;
}
.rightSvg {
float: right;
height: 40px;
line-height: 40px;
font-size: 36px;
padding-right: 40px;
padding-top: 10px;
color: white;
}
.main_content {
width: 100%;
height: calc(100vh - 60px);
display: flex;
flex-flow: column nowrap;
}
.mainDiv {
margin-top: 60px;
flex: 1;
}
/*去除左側(cè)導(dǎo)航欄所有超鏈接的下劃線*/
.main_content .mainDiv .leftDiv ul a:hover {
text-decoration: none;
}
.leftDiv {
float: left;
width: calc(20% - 6px);
height: calc(100vh - 60px);;
background-color: #eaedf1;
}
.leftDiv div {
background-color: #f5f5f5;
padding-left: 10px;
height: 40px;
line-height: 40px;
}
.leftDiv li {
background-color: #fff;
padding-left: 30px;
height: 30px;
line-height: 30px;
color: #2f72ab;
}
.rightDiv {
float: left;
width: 80%;
height: calc(100vh - 60px);
margin-left: 5px;
overflow: scroll;
border-left: #e8e8e8 solid 1px;
}
/*用戶操作部分上方導(dǎo)航*/
.infor {
width: 100%;
height: 30px;
background-color: #f5f5f5;
padding-left: 20px;
line-height: 30px;
}
.infor ul li {
display: inline-block;
list-style-type: none;
}
.infor ul li a {
color: black;
}
.infor ul li a:hover {
text-decoration: none;
}
/*右側(cè)上方小導(dǎo)航部分,最后一部分文字顏色不一樣*/
.infor ul li a:last-child {
color: #828282;
}
.information {
width: 100%;
}
注意:
1.? 矢量圖下載與使用:iconfont-阿里巴巴矢量圖標(biāo)庫,按照官網(wǎng)流程操作。
2.? 注意margin的使用——相鄰塊元素合并與嵌套塊元素塌陷。建議多用padding。
3. CSS各個單位的區(qū)別:px、pt、em、rem、vh、vw。參考前輩文章常見CSS單位總結(jié)_css 相對單位-CSDN博客
4. 自動填充頁面剩余部分:使用Flex布局 - - > 參考前輩文章Flex布局詳解-CSDN博客
二. Django前端調(diào)整
添加?{% block style %}{% endblock %}?用于其他頁面添加CSS代碼;使用?{{ title }}?用于不同的標(biāo)題, {{ username }} 同理。
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
<link rel="stylesheet" type="text/css" href="{% static 'base/scripts/svg_img/iconfont.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'base/css/base.css' %}">
{% block style %}{% endblock %}
</head>
<body>
<nav class="nav_top">
<div class="leftNav iconfont"> 刷票管理平臺</div>
<div class="rightSvg iconfont"></div>
<div class="rightNav">{{ username }}</div>
</nav>
用戶操作部分:
{% block spans %}{% endblock %} 用于修改上方小導(dǎo)航;{% block information %}{% endblock %} 用于添加主題內(nèi)容。
<div class="rightDiv">
<div class="infor">
{% block spans %}
{% endblock %}
</div>
<div class="information">
{% block information %}
{% endblock %}
</div>
</div>
至此結(jié)束。
Django 用戶資料界面編寫
目標(biāo):
一. 前端頁面
引入公共部分 base.html
{% extends 'base_html/base.html' %}
引入CSS文件和Bootstrap
{% load static %}
{% block style %}
<link rel="stylesheet" id="bootstrap-css">
<link rel="stylesheet" type="text/css" href="{% static 'user/css/user.css' %}">
{% endblock %}
右側(cè)上方小導(dǎo)航部分:
{% block spans %}
<ul>
<li>
<a href="#"><span>用戶信息</span></a>
<span>/</span>
</li>
<li>
<a href="#"><span>個人資料</span></a>
</li>
</ul>
{% endblock %}
右側(cè)主體部分:
{% block information %}
{# 左側(cè)用戶資料 #}
<div class="myInfo">
<div class="iconfont"> 我的資料</div>
<div>
<table>
<tbody>
<tr>
<td>用戶名</td>
<td>{{ username }}</td>
</tr>
<tr>
<td>賬戶余額</td>
<td>{{ balance }}</td>
</tr>
<tr>
<td>注冊時間</td>
<td>{{ regTime }}</td>
</tr>
</tbody>
</table>
</div>
</div>
{# 右側(cè)修改密碼 #}
<div class="pwdChange">
<div class="iconfont"> 修改密碼</div>
<div>
<form id="pwd-form" method="post" role="form" novalidate>
{% csrf_token %}
<table>
<tbody>
<tr>
<td>密碼</td>
<td>{{ form.enterPwd }}</td>
</tr>
<tr>
<td>確認(rèn)密碼</td>
<td>{{ form.ensurePwd }}</td>
</tr>
<tr>
<td></td>
<td>
<button type="submit" class="form-control">提交</button>
<span class="error_massage">
{{ form.ensurePwd.errors }}
</span>
</td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
{% endblock %}
CSS代碼:
/*左側(cè)導(dǎo)航欄左邊裝飾效果*/
.leftDiv .user_info > a:first-child li {
border-left: #2f72ab solid 5px;
padding-left: 25px;
}
/*Flex布局*/
.information{
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
}
.information .myInfo{
margin-left: 25px;
width: 47%;
margin-top: 25px;
height: 250px;
}
.information .pwdChange{
margin-right: 25px;
width: 47%;
margin-top: 25px;
height: 250px;
}
/*左側(cè)用戶資料*/
/*上面的名字*/
.information .myInfo div:first-child{
width: 100%;
height: 50px;
border: #eaedf1 solid 2px;
background-color: #f5f5f5;
line-height: 50px;
padding-left: 20px;
font-weight: bold;
}
.information .myInfo div:last-child{
width: 100%;
height: 200px;
border: #eaedf1 solid 2px;
border-top: #eaedf1 solid 0;
}
.information .myInfo div table{
padding-top: 20px;
padding-left: 36px;
border-collapse: initial;
}
.information .myInfo div table tr td{
padding: 10px;
}
.information .myInfo div table tr td:first-child{
text-align: right;
font-weight: bold;
}
/*右側(cè)·修改密碼*/
.information .pwdChange div:first-child{
width: 100%;
height: 50px;
border: #eaedf1 solid 2px;
background-color: #f5f5f5;
line-height: 50px;
padding-left: 20px;
font-weight: bold;
}
.information .pwdChange div:last-child{
width: 100%;
height: 200px;
border: #eaedf1 solid 2px;
border-top: #eaedf1 solid 0;
}
.information .pwdChange div table{
padding-top: 20px;
padding-left: 36px;
border-collapse: initial;
}
.information .pwdChange div table tr td{
padding: 10px;
}
.information .pwdChange div table tr td:first-child{
text-align: right;
font-weight: bold;
}
.information .pwdChange div table tr button{
width: 27%;
height: 30px;
line-height: 5px
}
.error_massage li{
color: red;
list-style-type: none;
padding-top: 5px;
}
二. Django后端各種py文件
urls.py:
int:id 用于傳輸?shù)卿浻脩舻膇d,便于后續(xù)查詢數(shù)據(jù)庫。
name:"user_view"?方便后續(xù)跳轉(zhuǎn)網(wǎng)頁。
path('user/<int:id>/', user_views.user, name="user_view"),
views.py:
和上一篇博客的login差不多,但存在問題,即修改密碼后刷新瀏覽器會出現(xiàn)警告“新密碼不應(yīng)該與舊密碼相同”
class pwdForm(forms.Form):
# 輸入新密碼
enterPwd = forms.CharField(
required=True,
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': "請輸入密碼", 'style': "width: 200%"}),
error_messages={"required": "該字段不能為空"},
label='輸入密碼'
)
# 確認(rèn)密碼
ensurePwd = forms.CharField(
required=True,
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': "請確認(rèn)密碼", 'style': "width: 200%"}),
error_messages={"required": "該字段不能為空"},
label='確認(rèn)密碼'
)
def user(request, **kwargs):
# 獲取數(shù)據(jù)庫數(shù)據(jù)
user_id = kwargs.get('id')
user_info = User.objects.get(id=user_id)
username = user_info.name
oldPwd = user_info.pwd
balance = user_info.balance
regTime = user_info.regTime
if request.method == "GET":
form = pwdForm()
return render(request, 'user_html/user.html',
{"form": form, "title": "用戶界面", "username": username, "balance": balance, "regTime": regTime,
"userId": user_id})
elif request.method == 'POST':
form = pwdForm(request.POST)
if form.is_valid():
# 輸入新密碼
enterPwd = form.cleaned_data['enterPwd']
# 確認(rèn)密碼
ensurePwd = form.cleaned_data['ensurePwd']
if enterPwd == ensurePwd and enterPwd != oldPwd:
User.objects.filter(id=user_id).update(pwd=enterPwd)
form.add_error("ensurePwd", "密碼修改成功")
return render(request, "user_html/user.html",
{"form": form, id: user_id, "title": "用戶界面", "username": username, "balance": balance,
"regTime": regTime, "userId": user_id})
# 瀏覽器刷新后自動提交表單導(dǎo)致出現(xiàn)"新密碼不應(yīng)該與舊密碼相同"提醒
elif enterPwd == ensurePwd and enterPwd == oldPwd:
form.add_error("ensurePwd", "新密碼不應(yīng)該與舊密碼相同")
return render(request, "user_html/user.html",
{"form": form, id: user_id, "title": "用戶界面", "username": username, "balance": balance,
"regTime": regTime, "userId": user_id})
else:
form.add_error("ensurePwd", "兩次密碼不一致")
return render(request, "user_html/user.html",
{"form": form, id: user_id, "title": "用戶界面", "username": username, "balance": balance,
"regTime": regTime, "userId": user_id})
else:
form = pwdForm()
return render(request, 'user_html/user.html',
{"form": form, "title": "用戶界面", "username": username, "balance": balance, "regTime": regTime,
"userId": user_id})
Django交易界面編寫
目標(biāo):
一. 前端頁面
使用bootstrap即可,沒什么注意點。
二. Django分頁器Paginator
此處參考了這位前輩的文章:Django 使用Paginator分頁器_django paginator-CSDN博客
from django.core.paginator import Paginator
2.0?創(chuàng)建數(shù)據(jù)庫
class Transaction(models.Model):
ACTION_STATES = {
"Y": "已執(zhí)行",
"N": "待執(zhí)行"
}
username = models.CharField(verbose_name='用戶名', max_length=32)
actionDate = models.DateField(verbose_name='交易日期', auto_now=True)
actionNumber = models.CharField(verbose_name='訂單號', max_length=32, default="")
aimUrl = models.CharField(verbose_name='目標(biāo)URL', max_length=256)
actionAmount = models.IntegerField(verbose_name='刷單數(shù)量', default=0)
# 最大數(shù)位為5,小數(shù)點后保留兩位小數(shù)
originalPrice = models.DecimalField(verbose_name='原價', max_digits=5, decimal_places=2, default=0.00)
deductionPrice = models.DecimalField(verbose_name='折扣價', max_digits=5, decimal_places=2, default=0.00)
originalBroadcast = models.CharField(verbose_name="原播放量", max_length=32, default="0")
actionState = models.CharField(verbose_name="狀態(tài)", max_length=1, choices=ACTION_STATES, default="N")
note = models.CharField(verbose_name="備注", max_length=128, default="測試")
注意點:
(1). choices
ACTION_STATES = {
"Y": "已執(zhí)行",
"N": "待執(zhí)行"
}
actionState = models.CharField(verbose_name="狀態(tài)", max_length=1, choices=ACTION_STATES, default="N")
方便操作,后續(xù)使用時,object.actionState = "Y",?object.get_actionState_display = "已執(zhí)行"。
(2). 保留兩位小數(shù)
originalPrice = models.DecimalField(verbose_name='原價', max_digits=5, decimal_places=2, default=0.00)
max_digits=5:最大數(shù)位為5;decimal_places=2:保留兩位小數(shù)。
2.1 創(chuàng)建實例
order_info = Transaction.objects.filter(username=username)
paginator = Paginator(order_info, 10) # 數(shù)據(jù)來源為order_info,每頁最多十行數(shù)據(jù)
page = request.GET.get('page', 1) # 獲取當(dāng)前請求的頁碼,默認(rèn)為第一頁
currentData = paginator.get_page(page) # 獲取第一頁的數(shù)據(jù),傳遞到前端頁面
前端代碼:
<tbody>
{% for order in currentDate %}
<tr>
<td>{{ order.actionDate }}</td>
<td>{{ order.actionNumber }}</td>
<td>{{ order.aimUrl }}</td>
<td>{{ order.actionAmount }}</td>
<td>¥{{ order.originalPrice }}</td>
<td>¥{{ order.deductionPrice }}</td>
<td>{{ order.originalBroadcast }}</td>
<td>{{ order.get_actionState_display }}</td>
<td>{{ order.note }}</td>
</tr>
{% endfor %}
</tbody>
分頁效果:
<ul class="pagination">
{% if order_list.has_previous %}
<li class="page-item"><a class="page-link" href="?id={{ currentData.previous_page_number }}">上一頁</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#">上一頁</a></li>
{% endif %}
{# ... #}
</ul>
2.3 優(yōu)化
def YSP(request, **kwargs):
user_id = kwargs.get('id')
user_info = User.objects.get(id=user_id)
username = user_info.name
# 獲取分頁數(shù)據(jù)
order_info = Transaction.objects.filter(username=username)
# 創(chuàng)建實例
orderPaginator = Paginator(order_info, 10)
currentPage = int(request.GET.get("id", 1))
# 當(dāng)數(shù)據(jù)大于10頁時,頁面只顯示10頁
if orderPaginator.num_pages > 15:
if currentPage - 5 < 1:
pageRange = range(1, 11)
elif currentPage + 5 > orderPaginator.num_pages:
pageRange = range(currentPage - 5, orderPaginator.num_pages)
else:
pageRange = range(currentPage - 5, currentPage + 5)
else:
pageRange = orderPaginator.page_range
# 分頁器id超出范圍時返回第一面或最后一面
try:
order_list = orderPaginator.page(currentPage)
except PageNotAnInteger:
order_list = orderPaginator.page(1)
except EmptyPage:
order_list = orderPaginator.page(orderPaginator.num_pages)
return render(request, "user_html/YSP.html", {"userId": user_id,
"username": username,
"order_list": order_list,
"paginator": orderPaginator,
"page_range": pageRange,
"currentPage": currentPage,
"title": "平臺分類"})
前端代碼:
<table class="table table-bordered">
<thead>
<tr>
<th>日期</th>
<th>訂單號</th>
<th>URL</th>
<th>數(shù)量</th>
<th>原價</th>
<th>折扣價</th>
<th>原播放量</th>
<th>狀態(tài)</th>
<th>備注</th>
<th>刪除</th>
</tr>
</thead>
<tbody>
{% for order in order_list %}
<tr>
<td>{{ order.actionDate }}</td>
<td>{{ order.actionNumber }}</td>
<td>{{ order.aimUrl }}</td>
<td>{{ order.actionAmount }}</td>
<td>¥{{ order.originalPrice }}</td>
<td>¥{{ order.deductionPrice }}</td>
<td>{{ order.originalBroadcast }}</td>
<td>{{ order.get_actionState_display }}</td>
<td>{{ order.note }}</td>
<td>
<form method="GET" action="./deleteOrder/">
{% csrf_token %}
<input type="hidden" name="order_actionNumber" value="{{ order.actionNumber }}">
<button type="submit" class="btn btn-danger btn-xs">刪除</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<nav class="d-flex justify-content-center" aria-label="Page navigation example">
<ul class="pagination">
{% if order_list.has_previous %}
<li class="page-item"><a class="page-link" href="?id={{ order_list.previous_page_number }}">上一頁</a>
</li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#">上一頁</a></li>
{% endif %}
{% for item in page_range %}
{% if item == currentPage %}
<li class="page-item active"><a class="page-link" href="?id={{ item }}">{{ item }}</a></li>
{% else %}
<li class="page-item"><a class="page-link" href="?id={{ item }}">{{ item }}</a></li>
{% endif %}
{% endfor %}
{% if order_list.has_next %}
<li class="page-item"><a class="page-link" href="?id={{ order_list.next_page_number }}">下一頁</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link" href="#">下一頁</a></li>
{% endif %}
<li class="page-item">
<span class="page-link" id="stataData"
style="color: #828282">共 {{ paginator.count }} 條數(shù)據(jù), 頁碼{{ currentPage }}/{{ paginator.num_pages }}頁</span>
</li>
</ul>
</nav>
2.4 實際效果
三. 添加與刪除訂單
目標(biāo)頁面:
后端代碼:
def createOrder(request, **kwargs):
user_id = kwargs.get('id')
user_info = User.objects.get(id=user_id)
username = user_info.name
if request.method == 'POST':
form = CORForm(request.POST)
if form.is_valid():
aimUrl = form.cleaned_data['aimUrl']
actionAmount = form.cleaned_data['actionAmount']
note = form.cleaned_data['note']
actionNumber = ''.join(str(random.randint(0, 9)) for _ in range(22))
originalPrice = 0.0004 * actionAmount
Transaction.objects.create(username=username, actionNumber=actionNumber, aimUrl=aimUrl,actionAmount=actionAmount, originalPrice=originalPrice, note=note)
return redirect("YSP", id=user_id)
else:
form = CORForm()
return render(request, "user_html/createOrder.html",
{"userId": user_id, "username": username, "form": form, "title": "平臺分類"})
def deleteOrder(request, **kwargs):
user_id = kwargs.get('id')
user_info = User.objects.get(id=user_id)
username = user_info.name
if request.method == 'POST':
delete_actionNumber = request.POST.get("order_actionNumber")
order_info = Transaction.objects.get(actionNumber=delete_actionNumber)
order_info.delete()
return redirect("YSP", id=user_id)
else:
delete_actionNumber = request.GET.get("order_actionNumber")
order_info = Transaction.objects.get(actionNumber=delete_actionNumber)
return render(request, "user_html/deleteOrder.html",
{"userId": user_id, "username": username, "order": order_info, "title": "平臺分類"})
普通的增加 Transaction.objects.create() 和
刪除 Transaction.objects.get(actionNumber=delete_actionNumber).delete() 。
四. 交易記錄頁面
創(chuàng)建數(shù)據(jù)庫
class Operation(models.Model):
OPERATIONS = {
"D": "刪除訂單",
"C": "創(chuàng)建訂單",
"O": "執(zhí)行訂單",
}
NOTES = {
"Y": "央視頻播放",
"B": "B站播放",
"T": "B站30%播放",
}
username = models.CharField(verbose_name='用戶名', max_length=32, default="")
actionNumber = models.CharField(verbose_name='訂單號', max_length=32, default="")
transactionAmountSign = models.CharField(verbose_name='交易金額正負(fù)', max_length=1, default="+")
transactionAmount = models.DecimalField(verbose_name='交易金額', max_digits=5, decimal_places=2, default=0.00)
operator = models.CharField(verbose_name='操作員', max_length=32, default="-")
actionDate = models.DateField(verbose_name='交易日期', auto_now=True)
operation = models.CharField(verbose_name='操作類型', max_length=1, choices=OPERATIONS)
note = models.CharField(verbose_name="備注", max_length=1, choices=NOTES)
后端代碼編寫:
由于分頁器用得比較多,所以包裝成函數(shù)文章來源:http://www.zghlxwxcb.cn/news/detail-846462.html
def makePagination(data_list, request):
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
Paginator = Paginator(data_list, 10)
currentPage = int(request.GET.get("id", 1))
if Paginator.num_pages > 15:
if currentPage - 5 < 1:
pageRange = range(1, 11)
elif currentPage + 5 > Paginator.num_pages:
pageRange = range(currentPage - 5, Paginator.num_pages)
else:
pageRange = range(currentPage - 5, currentPage + 5)
else:
pageRange = Paginator.page_range
try:
page_list = Paginator.page(currentPage)
except PageNotAnInteger:
page_list = Paginator.page(1)
except EmptyPage:
page_list = Paginator.page(Paginator.num_pages)
page_list = {"page_list": page_list, "Paginator": Paginator, "pageRange": pageRange, "currentPage": currentPage}
return page_list
def transaction(request, **kwargs):
user_id = kwargs.get('id')
user_info = User.objects.get(id=user_id)
username = user_info.name
operation_info = Operation.objects.filter(username=username)
page_list = makePagination(operation_info, request)
return render(request, "user_html/transaction.html", {"userId": user_id,"username": username,"operation_list": page_list['page_list'],"paginator": page_list['Paginator'],"page_range": page_list['pageRange'],"currentPage": page_list['currentPage'],"title": "交易記錄"})
關(guān)于頂部快速篩選的button,先欠著,以后再補文章來源地址http://www.zghlxwxcb.cn/news/detail-846462.html
到了這里,關(guān)于Django 管理平臺用戶界面編寫的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!