一、bootstrap模板使用
1.去bootstrap官网找一个合适的模板,下载下来,右键另存为即可
bootstrap官网---->bootstrap中文文档3-------->起步-------->找到合适模板------>右键另存为
2.在项目目录下新建statics目录,在statics目录下新建4个子目录,分别是:css、js、image、plugin,将下载下来的js放到js目录,css放到css目录,图片放到image目录
3.settings.py也要指定静态文件目录
STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR,'statics'), )
3.将下载下来的网页放在templates目录下,并改名为base.html,它基本上全是css和js,它将被用作公共模板,
再创建一个index.html,index放的是下载下来的网页去掉css和js的部分,主要是公共内容和框架,它将被用做app网页的模板
然后在templates目录下新建一个app的目录:app,app目录用来存放app自己的页面。
base.html
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<!DOCTYPE html> <html lang="zh-CN"> <head><meta http-equiv="Content-Type" content="text/html; 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=""> {# meta全部保留,IE浏览器相关的可要可不要,图标与css也要全部保留#} <link rel="icon" href="http://v3.bootcss.com/favicon.ico"> <title>王腾的个人站点</title> <link href="/static/css/bootstrap.min.css" rel="stylesheet"> <link href="/static/css/dashboard.css" rel="stylesheet"> {% block header-resources %} {% endblock %} {# 这里留一个block块,可以方便其他网页继承时进行扩展 来添加自定义样式#} </head> <body> {% block body %} {% endblock %} {# 这里留一个block body块,可以方便其他网页继承时进行扩展 在body里添加自定义的内容#} <script src="/static/js/jquery.min.js"></script> <script src="/static/js/bootstrap.min.js"></script> <script src="/static/js/holder.min.js"></script> {# 这些js全部保留,js的路径static是settings.py中STATIC_URL = '/static/'对应的STATIC_URL,而不是实际的目录名#} <script> {# 这里是自定义js,点击相应按钮时,按钮变颜色#} $(document).ready(function () { var current_url = "{{ request.path }}"; $('.nav-sidebar a[href="{{ request.path }}"]').parent().addClass('active'); }) </script> </body></html>
index.html
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
{% extends 'base.html' %} {#这里写继承base.html#} {% block body %} {# 这里在block body里自定义body的内容,要注意写上block body#} {% block nav-bar %} {# 这个block块是页面最上边的导航栏,为了其他页面可自定制导航栏,这里弄一个块,当其它页面写上 {% block nav-bar %}{% endblock %}时#} {# 其它页面的导航栏位置就不会显示模板的导航栏了#} <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="http://v3.bootcss.com/examples/dashboard/#">TEST</a> </div> <div id="navbar" class="navbar-collapse collapse"> <ul class="nav navbar-nav navbar-right"> <li><a href="http://v3.bootcss.com/examples/dashboard/#">Dashboard</a></li> <li><a href="http://v3.bootcss.com/examples/dashboard/#">Settings</a></li> <li><a href="http://v3.bootcss.com/examples/dashboard/#">Profile</a></li> <li class="dropdown"> {# 这里添加一个下拉菜单,也是找的模板上的#} <a href="http://v3.bootcss.com/examples/dashboard/#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{{ request.user.userprofile.name }}<span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="http://v3.bootcss.com/examples/dashboard/#">首页</a></li> <li><a href="/logout">注销</a></li> </ul> </li> </ul> <form class="navbar-form navbar-right"> <input type="text" class="form-control" placeholder="Search..."> </form> </div> </div> </nav> {% endblock %} <div class="container-fluid"> <div class="row"> {% block side-bar %} {# 这里写一个左边栏block块,也是为了其他页面可以自定制#} <div class="col-sm-3 col-md-2 sidebar"> <ul class="nav nav-sidebar"> {% block side-bar-menu %} {% for role in request.user.userprofile.roles.all %} <h3></h3> {# <li class="active"><a href="http://v3.bootcss.com/examples/dashboard/#">{{ role }}<span class="sr-only">(current)</span></a></li>#} {% for menu in role.menus.all %} <li> <a href="{% if menu.url_type == 0 %}{% url menu.url_name %}{% else %}{{ menu.url_name }} {# 这里的{% url menu.url_name %}就是取得数据库中的url_name,并且将这个url_name与urls.py中的name做比较,相同才可以跳转到相应页面,#} {% endif %}">{{ menu.name }}</a> </li> {% endfor %} {% endfor %} {% endblock %} </ul> </div> {% endblock %} {% block right-container %} <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main"> {% block right-container-content %} <h1 class="page-header">Dashboard</h1> <div class="row placeholders"> <div class="col-xs-6 col-sm-3 placeholder"> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail"> <h4>Label</h4> <span class="text-muted">Something else</span> </div> <div class="col-xs-6 col-sm-3 placeholder"> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail"> <h4>Label</h4> <span class="text-muted">Something else</span> </div> <div class="col-xs-6 col-sm-3 placeholder"> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail"> <h4>Label</h4> <span class="text-muted">Something else</span> </div> <div class="col-xs-6 col-sm-3 placeholder"> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail"> <h4>Label</h4> <span class="text-muted">Something else</span> </div> </div> <h2 class="sub-header">Section title</h2> {% endblock %} </div> {% endblock %} </div> </div> {% endblock %}
app/app.html
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
{% extends 'index.html' %} {% block right-container-content %} <h2 class="page-header">客户信息</h2> {{ request.path }} {% endblock %}
二.django管理界面设置
1.项目/urls.py
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
from django.conf.urls import url,include from django.contrib import admin from new import views #导入app的views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^crm/', include('crm.urls')), url(r'^login/', views.acc_login), #登录函数 url(r'^logout/', views.acc_logout), #注销函数 ]
2.app/urls.py
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
from django.conf.urls import url,include from django.contrib import admin from crm import views 导入app的views urlpatterns = [ url(r'^$', views.dashboard,name='sales'), # 设置该页面为首页 url(r'^customer$', views.customer,name='customer'), # 注意这里的name='customer'的字段customer要与数据库中的url_name 存的customer完全相同才行 ]
3.项目/views.py(使用django自带的登录验证)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#!/usr/bin/python # -*- coding:utf-8 -*- # author:wt from django.shortcuts import render,redirect from django.contrib.auth import authenticate,login,logout # 使用django自带的认证,登录,登出系统 def acc_login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') user = authenticate(username=username,password=password) print('res',user.userprofile.name) if user: # 认证成功 login(request,user) # 将用户名写到session里 return redirect('/crm') return render(request,'login.html') def acc_logout(request): logout(request) # 登出 return redirect('/login')
app/vies.py
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
from django.shortcuts import render from django.contrib.auth.decorators import login_required # 添加用户验证,直接输入业务网址,会自动跳转到登录界面 # Create your views here. @login_required # 添加用户验证,直接输入业务网址,会自动跳转到登录界面 def dashboard(request): return render(request,'crm/dashboard.html') @login_required def customer(request): return render(request,'crm/customer.html')
setting.py
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR,'statics'), ) LOGIN_URL = '/login/' # 使用django自带的认证
4.app/models.py 创建app的表
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
from django.db import models from django.contrib.auth.models import User # Create your models here. class Customer(models.Model): # 客户表 name = models.CharField(max_length=32) qq = models.CharField(max_length=64, unique=True) weixin = models.CharField(max_length=64, blank=True, null=True) phone = models.PositiveIntegerField(blank=True, null=True) # 只能存正数 age = models.PositiveSmallIntegerField(blank=True,null=True) gender = models.PositiveIntegerField(choices=((0,'男'),(1,'女'))) source_choices = ((0, '百度商桥'), (1,'51CTO'), (2,'QQ群'), (3,'知乎'), (4,'SOGO'), (5,'转介绍'), ) source = models.SmallIntegerField(choices=source_choices) # 存0-65535的数字 referral_from = models.ForeignKey('self',related_name='my_referreals', blank=True,null=True,verbose_name='转介绍') # 存转介绍的学生,关联自己表,‘related_name’用于反向查找 consult_courses = models.ManyToManyField('Course') # 咨询的课程 status_choices = ((0,'已报名'), (1,'未报名'), (2,'已退学'), ) status = models.SmallIntegerField(choices=status_choices) # 报名状态 consulttant = models.ForeignKey('UserProfile',verbose_name='课程顾问') # 课程顾问 consult_content = models.TextField(max_length=1024) # 学生描述 date = models.DateTimeField(auto_now_add=True) #auto_now_add 创建记录时,自动添加创建时间,auto_now修改记录时,将创建时间改为修改时的时间 def __str__(self): return '%s' % self.name # 注意这里都要返回字符串,不能直接返回self.name,会报错,也不能不返回东西,否则在管理界面会看到一堆object字母 class Emrollment(models.Model): # 学生报名表,只要有报名,就会创建一条学生与所报课程的记录 customer = models.ForeignKey('Customer') class_grade = models.ForeignKey('ClassList') enrollment_date = models.DateField() # 报名日期 def __str__(self): return '%s' % self.customer class Meta: unique_together = ('customer','class_grade') # 设置联合唯一 class FollowUpRecord(models.Model): # 跟进记录表 customer = models.ForeignKey('Customer') content = models.TextField(max_length=1024) status_choices = ((0, '绝无报名计划'), (1, '一个月内报名'), (2, '半个月内报名'), (2, '已选择其他机构'), ) status = models.SmallIntegerField(choices=status_choices) # 报名状态 consulttant = models.ForeignKey('UserProfile', verbose_name='课程顾问') # 课程顾问 date = models.DateTimeField(auto_now_add=True) #auto_now_add 创建记录时,自动添加创建时间,auto_now修改记录时,将创建时间改为修改时的时间 def __str__(self): return "%s" % self.customer class Course(models.Model): # 课程表 name = models.CharField(unique=True,max_length=64) price = models.PositiveIntegerField(default=19800) outline = models.TextField() # 课程大纲 def __str__(self): return '%s' % self.name class ClassList(models.Model): # 班级表 course = models.ForeignKey('Course') semester = models.PositiveSmallIntegerField(verbose_name='学期') class_type_choices = ((0,'脱产'), (1,'周末'), (2,'网络'), ) branch = models.ForeignKey('Branch') class_type = models.PositiveSmallIntegerField(choices=class_type_choices) teachers = models.ManyToManyField('UserProfile') start_date = models.DateField() end_date = models.DateField() def __str__(self): return '%s' % self.course class CourseRecord(models.Model): # 每节课上课记录与考勤 class_grade = models.ForeignKey('ClassList') day_number = models.PositiveSmallIntegerField(verbose_name='节次') teacher = models.ForeignKey('UserProfile') course_content = models.TextField(verbose_name='课程内容',max_length=1024) homework = models.BooleanField(default=True) homework_title = models.CharField(max_length=128,blank=True,null=True) homework_requirment = models.TextField(verbose_name='作业需求',max_length=1024,blank=True,null=True) def __str__(self): return '%s daynum:%s' % (self.class_grade,self.day_number) class Meta: unique_together = ('class_grade','day_number') class StudyRecord(models.Model): # 每个学生的每节课的成绩记录 course_record = models.ForeignKey('CourseRecord') student = models.ForeignKey('Emrollment') score_choices = ((100,'A+'), (90,'A'), (85,'B+'), (80,'B'), (75,'B-'), (70,'C+'), (65,'C'), (40,'C-'), (-20,'D'), (-50,'COPY'), (0,'N/A'), ) score = models.SmallIntegerField(choices=score_choices) show_status_choices = ((0,'缺勤'), (1,'迟到'), (2,'已签到'), ) show_status = models.SmallIntegerField(choices=score_choices) grade_comment = models.TextField(max_length=1024,blank=True,null=True) def __str__(self): return "%s student:%s" % (self.course_record,self.student) class Meta: unique_together = ('course_record','student') class UserProfile(models.Model): # 用户表 user = models.OneToOneField(User) name = models.CharField(max_length=32) roles = models.ManyToManyField('Role',blank=True,null=True) def __str__(self): return '%s' % self.name class Role(models.Model): # 角色管理 name = models.CharField(max_length=32,unique=True) menus = models.ManyToManyField('Menu') def __str__(self): return '%s' % self.name class Branch(models.Model): # 分校管理 name = models.CharField(max_length=128,unique=True) def __str__(self): return '%s' % self.name class Menu(models.Model): # 动态菜单 name = models.CharField(max_length=32,unique=True) url_type = models.SmallIntegerField(choices=((0,'relative_url'),(1,'absolut_url'))) url_name = models.CharField(unique=True,max_length=128) # 存储每个学生或员工的url def __str__(self): return '%s' % self.name
5.app/admin.py 使用django管理界面(进行app表注册)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
from django.contrib import admin from crm import models # Register your models here. class CustomerAdmin(admin.ModelAdmin): list_display = ('id','name','qq','consulttant','source','consult_content','status','date') # 在管理界面根据这些列明显示详细信息 list_filter = ('source','status','consulttant') # 在管理界面显示过滤条件 search_fields = ('qq','name') # 在管理界面增加搜索框,搜索条件是qq或name list_editable = ('status',) # 在管理界面增加status字段的编辑框 admin.site.register(models.Customer,CustomerAdmin) admin.site.register(models.FollowUpRecord) admin.site.register(models.Emrollment) admin.site.register(models.Course) admin.site.register(models.ClassList) admin.site.register(models.StudyRecord) admin.site.register(models.UserProfile) admin.site.register(models.Branch) admin.site.register(models.Role) admin.site.register(models.Menu) admin.site.register(models.CourseRecord)