django 阶段总结
2019-03-10 本文已影响0人
爱修仙的道友
项目介绍:
学生后台管理系统:
- 增、删、改、查
建立模板
1.合理利用Bootstrap
-
进入官网 --> Bootstrap3中文文档 --> 起步 --> 寻找控制台界面
image.png
2.创建base模板
- 将网页源代码,以及css导入项目中,并构建视图函数即路由
- views.py
from django.views import View
from django.shortcuts import render
class StudentIndex(View):
def get(self,request):
return render(request, 'students/index.html')
- urls.py
from django.urls import path
from . import views
app_name = 'index'
urlpatterns = [
path('index/', views.StudentIndex.as_view(), name='index'),
]
- 进入该路由,并对base.html页面进行设计,删除不需要的区域,并对动态区域进行block 挖坑
- 最终 base.html
{% load static %}
<!DOCTYPE html>
<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标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<meta name="description" content="">
<meta name="author" content="">
{% block title %}
{% endblock %}
<title>Dashboard Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="{% static 'css/base/dashboard.css' %}" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Student 管理系统</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">论坛</a></li>
<li><a href="#">文章</a></li>
<li><a href="#">学员</a></li>
<li><a href="#">退出</a></li>
</ul>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2 sidebar">
<ul class="nav nav-sidebar">
<li class="active"><a href="#">学生管理<span class="sr-only">(current)</span></a></li>
<li><a href="#">区域管理</a></li>
<li><a href="#">课程管理</a></li>
<li><a href="#">班级管理</a></li>
</ul>
<ul class="nav nav-sidebar">
<li><a href="">系统设置</a></li>
<li><a href="">权限管理</a></li>
</ul>
</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h2 class="sub-header">
{% block section %}
Base title
{% endblock %}
</h2>
{% block content %}
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Header</th>
<th>Header</th>
<th>Header</th>
<th>Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>1,001</td>
<td>Lorem</td>
<td>ipsum</td>
<td>dolor</td>
<td>sit</td>
</tr>
</tbody>
</table>
</div>
{% endblock %}
</div>
</div>
</div>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"><\/script>')</script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>
数据库设计
# models.py
from django.db import models
class Student(models.Model):
name = models.CharField(max_length=20)
age = models.SmallIntegerField(default=0)
sex = models.SmallIntegerField(default=0)
c_time = models.DateTimeField(auto_now_add=True)
e_time = models.DateTimeField(auto_now=True)
# 逻辑删除
is_delete = models.BooleanField(default=False)
# 第一个参数 'Area' 字符串格式,
# 不需要删除学生就删除地区,只需设置为空就好 on_delete=models.SET_NULL, null=True
area = models.ForeignKey('Area', on_delete=models.SET_NULL, null=True)
def __str__(self):
return '{}-{}'.format(self.id, self.name)
class StudentDetail(models.Model):
qq = models.CharField(max_length=15,default='')
phone = models.CharField(max_length=15,default='')
college = models.CharField(max_length=20,default='')
# models.OneToOneField('Student', on_delete=models.CASCADE)
# 第一个参数 相关联的主表(字符串格式)
# 第二个参数 级联操作 on_delete=models.CASCADE 主表删除,子表也对应删除
student = models.OneToOneField('Student', on_delete=models.CASCADE)
def __str__(self):
return '{}号学生详情'.format(self.id)
# 地区表
# 一个学生只能在一个地区,一个地区可以有多个学生,须在学生字段添加外键(多的一方添加外键)
class Area(models.Model):
address = models.CharField(max_length=20)
def __str__(self):
return '{}区域'.format(self.address)
# 课程表
class Course(models.Model):
course = models.CharField(verbose_name='课程名称', max_length=20)
# 多对多
# 第一个参数 'Student' 字符串格式,
# 第二个参数指定表,增加参数
student = models.ManyToManyField('Student', through='Enroll')
def __str__(self):
return '{}课程'.format(self.course)
class Enroll(models.Model):
student = models.ForeignKey('Student', on_delete=models.CASCADE)
course = models.ForeignKey('Course', on_delete=models.CASCADE)
pay = models.FloatField('缴费金额', default=0)
c_time = models.DateTimeField('报名时间', auto_now_add=True)
def __str__(self):
return '{}学生报名了{}课程'.format(self.student, self.course)
makemigrations index
migrate index
- 导入测试数据
# 进入shell界面
搜索功能
- index.html
{% extends 'base/base.html' %}
{% block title %}
学生列表
{% endblock %}
{% block section %}
{{ section }}
{% endblock %}
{% block content %}
{# 内联搜索表单 #}
<form class="form-inline" style="margin-bottom: 10px" method="get">
<div class="form-group">
<label for="exampleInputName2"></label>
<input type="text" class="form-control" id="exampleInputName2" name="search" placeholder="学生姓名/qq/电话" value={{ search }}>
</div>
<button type="submit" class="btn btn-default">搜索</button>
<a class="btn btn-default" href="{% url 'index:index' %}">重置</a>
</form>
{# 表单详情 #}
<div class="table-responsive">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>QQ</th>
<th>电话</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for student in students %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ student.name }}</td>
<td>{{ student.age }}</td>
<td>{{ student.sex }}</td>
<td>{{ student.studentdetail.qq|default:'未填' }}</td>
<td>{{ student.studentdetail.phone|default:'未填' }}</td>
{# 该处信息 https://v3.bootcss.com/css/#buttons 都可以找到信息 #}
<td><a href="#" class="btn btn-primary btn-xs active" role="button">编辑</a>|<a href="{% url 'index:delete' student.id %}" class="btn btn-primary btn-xs btn-danger" role="button">删除</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
- views.py
from django.db.models import Q
from django.views import View
from django.shortcuts import render
from . import models
class StudentIndex(View):
def get(self,request):
search = request.GET.get('search', '').strip()
if search:
if search.isdigit():
students = models.Student.objects.select_related('studentdetail'). \
only('name', 'age', 'sex', 'studentdetail__qq', 'studentdetail__phone').filter(
Q(studentdetail__qq=search)|Q(studentdetail__phone=search), is_delete=False).order_by('-e_time')
else:
students = models.Student.objects.select_related('studentdetail'). \
only('name', 'age', 'sex', 'studentdetail__qq', 'studentdetail__phone').filter(
is_delete=False,name__icontains=search).order_by('-e_time')
else:
# 当数据量很大时,需要分页取值
students = models.Student.objects.select_related('studentdetail').\
only('name','age','sex','studentdetail__qq','studentdetail__phone').filter(is_delete=False).order_by('-e_time')
section = '学生列表'
context = {
'section':section,
'students':students,
'search':search,
}
return render(request, 'students/index.html', context=context)
- urls.py
from django.urls import path
from . import views
app_name = 'index'
urlpatterns = [
path('index/', views.StudentIndex.as_view(), name='index'),
]
-
展示
image.png
删除功能
- views.py
class StudentDelete(View):
def get(self,request, student_id):
stu = models.Student.objects.only('id').filter(is_delete=False,id=student_id).first()
if stu:
stu.is_delete=True
stu.save()
return redirect(reverse('index:index'))
- urls.py
from django.urls import path
from . import views
app_name = 'index'
urlpatterns = [
path('index/', views.StudentIndex.as_view(), name='index'),
path('delete/<int:student_id>/', views.StudentDelete.as_view(), name='delete'),
]
新增功能
class StudentAdd(View):
def get(self, request):
courses = models.Course.objects.all()
area = models.Area.objects.all()
context = {
'courses':courses,
'area':area,
}
return render(request, 'students/edit.html',context=context)
def post(self, request):
data = {
'name':request.POST.get('username',None),
'age':request.POST.get('age',None),
'sex':request.POST.get('sex',None),
'area_id':request.POST.get('area',None),
}
# 主表保存
student = models.Student(**data)
student.save()
# 从表保存
student_datail =models.StudentDetail(
qq = request.POST.get('qq', None),
phone = request.POST.get('phone', None),
student = student
)
student_datail.save()
enroll = models.Enroll(
course=models.Course.objects.filter(id=request.POST.get('course',None)).first(),
student = student
)
enroll.save()
return redirect(reverse('index:index'))
编辑功能
class StudentEdit(View):
def get(self, request, student_id):
student = models.Student.objects.select_related('studentdetail','area').filter(is_delete=False,id=student_id).first()
courses = models.Course.objects.all()
area = models.Area.objects.all()
return render(request,'students/edit.html',locals())
def post(self, request, student_id):
student = models.Student.objects.select_related('studentdetail','area').filter(id=student_id).first()
student.name = request.POST.get('username', None)
student.age = request.POST.get('age', None)
student.sex = request.POST.get('sex', None)
student.area_id = request.POST.get('area', None)
student.save()
# 从表保存
student.studentdetail.qq =request.POST.get('qq', None)
student.studentdetail.phone=request.POST.get('phone', None)
student.studentdetail.save()
enroll = models.Enroll(
course=models.Course.objects.filter(id=request.POST.get('course', None)).first(),
student=student
)
enroll.save()
return redirect(reverse('index:index'))
{% extends 'base/base.html' %}
{% block title %}
学生详情
{% endblock %}
{% block section %}
{{ section }}
{% endblock %}
{% block content %}
<form class="form-horizontal" method="post">
{% csrf_token %}
<div class="form-group">
<label for="username" class="col-sm-2 control-label">姓名</label>
<div class="col-sm-2">
<input type="text" name="username" class="form-control" id="username" value="{{ student.name }}" placeholder="姓名">
</div>
</div>
<div class="form-group">
<label for="age" class="col-sm-2 control-label">年龄</label>
<div class="col-sm-2">
<input type="text" name="age" class="form-control" id="age" value="{{ student.age }}" placeholder="年龄">
</div>
</div>
<div class="form-group">
<label for="sex" class="col-sm-2 control-label">性别</label>
<div class="col-sm-2">
<label class="radio-inline">
<input type="radio" name="sex" id="sex1" value="1" {% if student.sex == 1 %} checked {% endif %} > 男
</label>
<label class="radio-inline">
<input type="radio" name="sex" id="sex2" value="0" {% if student.sex == 0 %} checked {% endif %}> 女
</label>
</div>
</div>
<div class="form-group">
<label for="qq" class="col-sm-2 control-label">QQ</label>
<div class="col-sm-2">
<input type="text" name="qq" class="form-control" id="qq" placeholder="QQ" value="{{ student.studentdetail.qq }}">
</div>
</div>
<div class="form-group">
<label for="phone" class="col-sm-2 control-label">电话</label>
<div class="col-sm-2">
<input type="text" name="phone" class="form-control" id="phone" value="{{ student.studentdetail.phone}}" placeholder="电话">
</div>
</div>
<div class="form-group">
<label for="course" class="col-sm-2 control-label">课程</label>
<div class="col-sm-2">
<select class="form-control" name="course">
<option name="course" value="">{{ student.enroll_set.last.course|default:'未填' }}</option>
{% for foo in courses %}
<option name="course" value="{{ foo.id }}" >{{ foo.course }} </option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<label for="addr" class="col-sm-2 control-label">区域</label>
<div class="col-sm-2">
<select class="form-control" name="area">
<option name="course" value="">{{ student.area.address|default:'未填' }}</option>
{% for foo in area %}
<option name="area" value="{{ foo.id }}">{{ foo.address }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-2 col-xs-2 ">
{% if student_id %}
<button type="submit" class="btn btn-default">更新</button>
{% else %}
<button type="submit" class="btn btn-default">保存</button>
{% endif %}
</div>
</div>
</form>
{% endblock %}