1 創建學員系統表結構
models
#_*_coding:utf-8_*_ from django.db import models # Create your models here. # Django練習小項目:學員管理系統設計開發 # 帶着項目需求學習是最有趣和效率最高的,今天就來基於下面的需求來繼續學習Django # # 項目需求: # # 1.分講師\學員\課程顧問角色, # 2.學員可以屬於多個班級,學員成績按課程分別統計 # 3.每個班級至少包含一個或多個講師 # 4.一個學員要有狀態轉化的過程 ,比如未報名前,報名后,畢業老學員 # 5.客戶要有咨詢紀錄, 后續的定期跟蹤紀錄也要保存 # 6.每個學員的所有上課出勤情況\學習成績都要保存 # 7.學校可以有分校區,默認每個校區的員工只能查看和管理自己校區的學員 # 8.客戶咨詢要區分來源 # Create your models here. from django.core.exceptions import ValidationError from django.db import models from django.contrib.auth.models import User class_type_choices= (('online',u'網絡班'), ('offline_weekend',u'面授班(周末)',), ('offline_fulltime',u'面授班(脫產)',), ) #1用戶表(講師,銷售,課程顧問,學校工作人員) class UserProfile(models.Model): #UserProfile是對默認基本表User的繼承和擴展 user = models.OneToOneField(User) #一對一是外鍵的特例,下拉框選擇一次后,下次就不能再次選擇 unique name = models.CharField(u"姓名",max_length=32) #UserProfile相當於用戶詳細表,User相當於用戶基本表(djangomore默認用戶表) 這2個表中name=alex只能是一對一 #在詳細表中,創建一條記錄是alex,對應基本表的alex;再次創建jack的時候,對應基本表就不能還是alex,必須是jack #所以用到的是一對一 def __unicode__(self): return self.name def __str__(self): return self.name class Meta: #表中文名在admin顯示 verbose_name = '校內工作人員表' verbose_name_plural = "校內工作人員表" #2校區表 class School(models.Model): name = models.CharField(u"校區名稱",max_length=64,unique=True) #名字 addr = models.CharField(u"地址",max_length=128) #地址 staffs = models.ManyToManyField('UserProfile',blank=True) #校區和學校工作人員UserProfile 多對多 #一個校區多個講師 一個講師(校長、領導)屬於多個校區 def __unicode__(self): return self.name def __str__(self): return self.name class Meta: #表中文名在admin顯示 verbose_name = '校區表' verbose_name_plural = "校區表" #3課程表 class Course(models.Model): name = models.CharField(u"課程名稱",max_length=128,unique=True) #課程名字 python linux price = models.IntegerField(u"面授價格") #面授價格 online_price = models.IntegerField(u"網絡班價格") #網絡班價格 brief = models.TextField("課程簡介") #參數中的"課程簡介"就相當於是字段的中文別名,顯示在admin頁面 # brief = models.TextField() #參數中的"課程簡介"就相當於是字段的中文別名,顯示在admin頁面 def __unicode__(self): return self.name def __str__(self): return self.name #在admin中每條記錄顯示課程的名字 class Meta: #表中文名在admin顯示 verbose_name = '課程表' verbose_name_plural = "課程表" #4班級表 class ClassList(models.Model): course = models.ForeignKey('Course') #外鍵,對應另外一張表的一條記錄,本表顯示course_id # 班級和課程是一對多,一個課程包含多個班級(python就包含python11期、python12期) # 外鍵,下拉框單選課程 course_type = models.CharField(u"課程類型",choices=class_type_choices,max_length=32)#對應26行 # 非外鍵,下拉框單選(和外鍵的區別是,外鍵是取的另外一張表的數據,而非外鍵單選是取的26行元組中的數據,頁面顯示元組靠后的元素) semester = models.IntegerField(u"學期") #11期 12期 start_date = models.DateField(u"開班日期") #默認必選 graduate_date = models.DateField(u"結業日期",blank=True,null=True) #允許為空 teachers = models.ManyToManyField(UserProfile,verbose_name=u"講師") #字段顯示中文在admin 多對多 #一個班多個老師,一個老師帶多個班 def __unicode__(self): return "%s(%s)" %(self.course.name,self.course_type) def __str__(self): # return "%s[%s](%s)" %(self.course.name,self.semester,self.course_type) #顯示元組靠前的元素(offline_weekend) return "%s[%s](%s)" %(self.course.name,self.semester,self.get_course_type_display()) #顯示元組靠后的元素(面授班周末) 顯示漢字 get_course_type_display() 其中course_type是字段名 # 前端html也可以這么寫 get_course_type_display 需要去掉小括號 class Meta: #表中文名,和字段聯合惟一 verbose_name = u'班級列表' verbose_name_plural = u"班級列表" #表名顯示中文在admin unique_together = ("course","course_type","semester") #課程-python 課程類型:面授班 學期:11期 這個3個字段聯合惟一(不會出現2個python面授班11期) #5客戶表(學生) class Customer(models.Model): qq = models.CharField(u"QQ號",max_length=64,unique=True) #qq必須有,且惟一 name = models.CharField(u"姓名",max_length=32,blank=True,null=True) #姓名可以為空,剛剛咨詢的時候,一般不說真實名字 phone = models.BigIntegerField(u'手機號',blank=True,null=True) stu_id = models.CharField(u"學號",blank=True,null=True,max_length=64) #id = models.CharField(u"身份證號",blank=True,null=True,max_length=128) source_type = (('qq',u"qq群"), #學員渠道 ('referral',u"內部轉介紹"), ('51cto',u"51cto"), ('agent',u"招生代理"), ('others',u"其它"), ) source = models.CharField(u'客戶來源',max_length=64, choices=source_type,default='qq') referral_from = models.ForeignKey('self',verbose_name=u"轉介紹自學員",help_text=u"若此客戶是轉介紹自內部學員,請在此處選擇內部學員姓名",blank=True,null=True,related_name="internal_referral") #由誰轉介紹的,介紹人也是客戶表中的,自關聯外鍵(1對多,1個介紹人介紹多個學員) # related_name="internal_referral" 是固定寫法,反查用internal_referral字段 # 通過zhangxiaoyu.referral_from就可以查看張曉宇是誰推薦的(比如廖家發) # 通過介紹人廖家發,查廖家發推薦了誰,用liaojiafa.internal_referral反查到(張曉宇) course = models.ForeignKey(Course,verbose_name=u"咨詢課程") #外鍵一對多 class_type = models.CharField(u"班級類型",max_length=64,choices=class_type_choices)#26行 customer_note = models.TextField(u"客戶咨詢內容詳情",help_text=u"客戶咨詢的大概情況,客戶個人信息備注等...") status_choices = (('signed',u"已報名"), ('unregistered',u"未報名"), ('graduated',u"已畢業"), ) #學員狀態 status = models.CharField(u"狀態",choices=status_choices,max_length=64,default=u"unregistered",help_text=u"選擇客戶此時的狀態") consultant = models.ForeignKey(UserProfile,verbose_name=u"課程顧問") date = models.DateField(u"咨詢日期",auto_now_add=True) #自動加上時間 class_list = models.ManyToManyField('ClassList',verbose_name=u"已報班級",blank=True) #可以為空,如果已經報名了,就選班級 多對多(一個班級多個學員,一個學員報了多個班--dali,下拉框多選) #創建學員的時候,選擇班級,但是要查每個班級有多少人,就是個反向關聯 def __unicode__(self): return "%s,%s" %(self.qq,self.name ) def __str__(self): return "%s,%s" %(self.qq,self.name ) class Meta: #表中文名在admin顯示 verbose_name = '學員表' verbose_name_plural = "學員表" #6跟蹤記錄表 class ConsultRecord(models.Model): customer = models.ForeignKey(Customer,verbose_name=u"所咨詢客戶") #一對多,外鍵,一個學員可以有多條跟蹤記錄(每個跟蹤記錄只屬於一個學員) note = models.TextField(u"跟進內容...") status_choices = ((1,u"近期無報名計划"), (2,u"2個月內報名"), (3,u"1個月內報名"), (4,u"2周內報名"), (5,u"1周內報名"), (6,u"2天內報名"), (7,u"已報名"), ) #近期的報名學習計划 status = models.IntegerField(u"狀態",choices=status_choices,help_text=u"選擇客戶此時的狀態") consultant = models.ForeignKey(UserProfile,verbose_name=u"跟蹤人") #一對多,外鍵,一個課程顧問可以有多條跟蹤記錄(每個跟蹤記錄只屬於一個課程顧問),下拉框是課程顧問(校內工作人員)的名字 date = models.DateField(u"跟進日期",auto_now_add=True) #自動添加當條記錄的跟蹤日期 # (第一次和課程顧問a聊的,2個月內,不管是和誰簽的,都算在a上,但是過了2個月,再和課程顧問b聊的,就算在b上了) def __unicode__(self): #py2.7 return u"%s, %s" %(self.customer,self.status) def __str__(self): #py3.5 # return u"%s, %s" %(self.customer,self.status) #顯示148元組的前面元素-key return u"%s, %s" %(self.customer,self.get_status_display()) #顯示148元組的后面元素-value class Meta: verbose_name = u'客戶咨詢跟進記錄' verbose_name_plural = u"客戶咨詢跟進記錄" #7課程記錄表 class CourseRecord(models.Model): course = models.ForeignKey(ClassList,verbose_name=u"班級(課程)") #外鍵,下拉框單選班級 內容從另外一個表取 day_num = models.IntegerField(u"節次",help_text=u"此處填寫第幾節課或第幾天課程...,必須為數字") #day19 date = models.DateField(auto_now_add=True,verbose_name=u"上課日期") teacher = models.ForeignKey(UserProfile,verbose_name=u"講師") #外鍵,下拉框單選老師,內容從校內工作人員表取-用戶表 def __unicode__(self): return u"%s 第%s天" %(self.course,self.day_num) def __str__(self): return u"%s 第%s天" %(self.course,self.day_num) #control控制台 顯示pythons12 day19 class Meta: verbose_name = u'上課紀錄' verbose_name_plural = u"上課紀錄" #表名中文顯示 unique_together = ('course','day_num') #聯合惟一 python面授 s12 day19不能出現2個一樣的 #8學習記錄表(某學員的學習記錄表) class StudyRecord(models.Model): course_record = models.ForeignKey(CourseRecord, verbose_name=u"第幾天課程") #外鍵,下拉框單選上課記錄(這里不能是一對一,如果是一對一,就意味中只有1個人能來上課 vip了) student = models.ForeignKey(Customer,verbose_name=u"學員") # student = models.OneToOneField(Customer,verbose_name=u"學員") #外鍵,下拉框單選學員的名字 每個學員只能有一個學習記錄--聯合惟一 226行 record_choices = (('checked', u"已簽到"), ('late',u"遲到"), ('noshow',u"缺勤"), ('leave_early',u"早退"), ) #簽到記錄(下拉框單選,但是區別於外鍵-外鍵是從別的表取數據) record = models.CharField(u"上課紀錄",choices=record_choices,default="checked",max_length=64) score_choices = ((100, 'A+'), (90,'A'), (85,'B+'), (80,'B'), (70,'B-'), (60,'C+'), (50,'C'), (40,'C-'), (0,'D'), (-1,'N/A'), (-100,'COPY'), (-1000,'FAIL'), ) #成績作業記錄(下拉框單選,但是區別於外鍵-外鍵是從別的表取數據) score = models.IntegerField(u"本節成績",choices=score_choices,default=-1) date = models.DateTimeField(auto_now_add=True) #自動添加日期時間 note = models.CharField(u"備注",max_length=255,blank=True,null=True) #備注可以為空 def __unicode__(self): return u"%s,學員:%s,紀錄:%s, 成績:%s" %(self.course_record,self.student.name,self.record,self.get_score_display()) #self.get_score_display()是為了顯示A B+等value 而不是顯示100 90分數 def __str__(self): # return u"%s,學員:%s,紀錄:%s, 成績:%s" %(self.course_record,self.student.name,self.record,self.get_score_display()) return u"%s,學員:%s,紀錄:%s, 成績:%s" %(self.course_record,self.student.name,self.get_record_display(),self.get_score_display()) class Meta: verbose_name = u'學員學習紀錄' verbose_name_plural = u"學員學習紀錄" #表的中文別名 unique_together = ('course_record','student') #聯合唯一 例如:小宇18天只能上一次,無法在18天上2次 #student的標識是qq號碼 # 學員管理系統表結構
2、admin.py
from django.contrib import admin # Register your models here. from app01 import models # class entryadmin(admin.ModelAdmin): # list_display = ("blog","headline","pub_date","mod_date","n_comments","n_pingbacks") class CourseRecordadmin(admin.ModelAdmin): #課程記錄表 list_display = ("course","day_num","teacher","date") #admin顯示表的字段,默認只顯示1個,這里可以多顯示幾個字段 admin.site.register(models.UserProfile) #學校工作人員 admin.site.register(models.School) #校區 admin.site.register(models.Course) #課程表 admin.site.register(models.ClassList) #班級表 admin.site.register(models.Customer) #學員表 admin.site.register(models.ConsultRecord) #跟蹤記錄表 admin.site.register(models.CourseRecord,CourseRecordadmin) #課程記錄表 admin.site.register(models.StudyRecord) #學習記錄表 # admin.site.register(models.Entry,entryadmin)
二、用戶認證
#需求1:用戶認證的實現,只有用戶登錄了,才能看到welcome to oldboy crm,如果用戶沒有登錄,是無法看到的
# 會自動跳轉到http://127.0.0.1:8000/accounts/login/?next=/index/,顯示登錄框
# 在這個頁面寫一個登錄前的頁面-html,輸入正確用戶名和密碼登錄后
# 注意,如果用戶已經登錄admin了,說明用戶已經登錄了,需要先退出admin登錄
#需求2:用戶認證成功后,前台顯示用戶名
#需求3:用戶退出
views
from django.shortcuts import render,HttpResponse,redirect,HttpResponseRedirect from django.contrib.auth.decorators import login_required #導入 from django.contrib.auth import authenticate,login #導入認證 # Create your views here. #需求1:用戶認證的實現,只有用戶登錄了,才能看到welcome to oldboy crm,如果用戶沒有登錄,是無法看到的 # 會自動跳轉到http://127.0.0.1:8000/accounts/login/?next=/index/,顯示登錄框 # 在這個頁面寫一個登錄前的頁面-html,輸入正確用戶名和密碼登錄后 # 注意,如果用戶已經登錄admin了,說明用戶已經登錄了,需要先退出admin登錄 #需求2:用戶認證成功后,前台顯示用戶名 #需求3:用戶退出--nok @login_required #裝飾器,1先導入2行,2再添加這個裝飾器后,就實現了需求1 def index(request): return render(request,"index.html") def acc_login(request): if request.method == "POST": #如果是post提交 print(request.POST) #<QueryDict: {'csrfmiddlewaretoken': ['YZijm5yl6wGLuaxUSr7Nfm0iuSh3PTF8'], # 'pwd': ['alex1234'], 'username': ['alex']}> user = authenticate(username=request.POST.get("username"),#獲取用戶輸入的用戶名和密碼,驗證后,存在user對象 password=request.POST.get("pwd")) if user is not None: #不為空,說明驗證通過 login(request,user) #將用戶名和密碼提交登錄,必須提交,否則有問題 # return HttpResponseRedirect("/index/") #跳轉到http://127.0.0.1:8000/index/頁面 return HttpResponseRedirect("/") #跳轉到http://127.0.0.1:8000/頁面 else: login_err = "wrong username or password!" #將錯誤信息作為第三個參數傳到前端html return render(request,"acc_login.html",{"login_err":login_err}) return render(request,"acc_login.html") #如果是get
html母板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>oldboy CRM</h1> {% block page-container %} {# 可以被子模板重寫 block#} <h1>welcome to oldboy crm</h1> <div> {% if request.user.is_authenticated %} <span> {# {{ request.user }}#} {# 15行這里只是顯示了用戶名,如何顯示用戶名對應的姓名?如何通過用戶基礎表查出用戶詳細表的姓名#} {# 通過user表查userprofile表 全小寫 18行#} {{ request.user.userprofile.name }} </span> {% else %} <span> 登錄/注冊 </span> {% endif %} </div> {% endblock %} </body> </html>
{% extends "index.html" %} {#繼承index模版#} {% block page-container %} {# 子模板重寫#} <form action="" method="post">{% csrf_token %} 用戶名:<input type="text" name="username"/> 密碼:<input type="password" name="pwd"/> <input type="submit" value="登錄"/> <div> {% if login_err %} {# 如果存在錯誤信息,將錯誤信息以紅色字體顯示在前端html#} <p style="color: red">{{ login_err }}</p> {% endif %} </div> </form> {% endblock %}
三、創建學員系統表結構和admin自定義字段
models.py
#_*_coding:utf-8_*_ from django.db import models # Create your models here. from django.core.exceptions import ValidationError from django.db import models from django.contrib.auth.models import User #導入User,django自帶用戶基礎表 course_type_choices = (('online',u'網絡班'), #元組嵌套元組,列表嵌套元組也可 ('offline_weekend',u'面授班(周末)',), ('offline_fulltime',u'面授班(脫產)',), ) #1校區表 class School(models.Model): name = models.CharField("校區名字",max_length=128,unique=True) #名字惟一 city = models.CharField("城市",max_length=64) #city是數據庫字段,城市在在admin中顯示的漢字別名 addr = models.CharField("地址",max_length=128) def __unicode__(self): #py2.7 return self.name def __str__(self): #py3.5 return self.name #admin中表的每條記錄顯示中文名字 class Meta: #admin頁面,表名顯示中文 verbose_name = '校區表' verbose_name_plural = "校區表" #2學校工作人員表(用戶表) class UserProfile(models.Model): user = models.OneToOneField(User,verbose_name=u"用戶名") #alex #用戶名 外鍵的特殊情況(一對一),不能重復 #下拉框選了一次不能再選,或者是可以再選,保存的時候提示錯誤 #User是django自帶的用戶表(用戶基本信息) UserProfile相當於用戶詳細信息表 #外鍵代表另外一個表的一條數據,一行記錄 #alex在用戶基本表和用戶詳細表都只有1個 name = models.CharField("姓名",max_length=64) #姓名 school = models.ForeignKey('School',verbose_name=u"校區") #校區 外鍵 下拉框單選校區 def __unicode__(self): return self.name def __str__(self): return self.name class Meta: #admin頁面,表名顯示中文 verbose_name = '學校工作人員表' verbose_name_plural = "學校工作人員表" #3學員表(客戶表) class Customer(models.Model): qq = models.CharField(max_length=64,unique=True) #qq惟一 name = models.CharField("姓名",max_length=32,blank=True,null=True) #默認必選,這里允許不填 phone = models.BigIntegerField("手機號碼",blank=True,null=True) course = models.ForeignKey('Course',verbose_name=u"課程") #外鍵 下拉框單選課程 外鍵不能直接寫中文別名,需要verbose_name course_type = models.CharField("課程類型",max_length=64,choices=course_type_choices,default='offline_weekend') #9行 course_type_choices consult_memo = models.TextField("咨詢備注") source_type_choices = (('qq',u"qq群"), #元組嵌套元組 列表嵌套元組 ('referral',u"內部轉介紹"), ('51cto',u"51cto"), ('agent',u"招生代理"), ('others',u"其它"), ) source_type = models.CharField("學員渠道",max_length=64,choices=source_type_choices) #這個也是下拉框單選,和外鍵的區別是:外鍵取的數據是來一張表 referral_from = models.ForeignKey('self',blank=True,null=True,related_name="referraled_who",verbose_name=u"推薦人") #推薦人 related_name="referraled_who"是固定寫法 外鍵關聯到自己,因為推薦人也是學員表中的學員 status_choices = (('signed',u"已報名"), #學員狀態 ('unregistered',u"未報名"), ('graduated',u"已畢業"), ('drop-off',u"退學"), ) status = models.CharField("學員狀態",choices=status_choices,max_length=64) consultant = models.ForeignKey('UserProfile',verbose_name=u"課程顧問") # 外鍵 下拉框單選一個課程顧問 class_list = models.ManyToManyField("ClassList",blank=True,verbose_name=u"班級") #多對多 下拉框多選班級(允許多選,也可以只選擇一個) date = models.DateField(u"咨詢日期",auto_now_add=True) def __unicode__(self): return "%s(%s)"%(self.qq,self.name) def __str__(self): return "%s(%s)"%(self.qq,self.name) class Meta: #admin頁面,表名顯示中文 verbose_name = '學員表' verbose_name_plural = "學員表" #4學員跟蹤記錄表 class CustomerTrackRecord(models.Model): customer = models.ForeignKey(Customer,verbose_name="學員") #外鍵 下拉框單選學員 track_record = models.TextField(u"跟蹤紀錄") track_date = models.DateField("跟蹤時間",auto_now_add=True) #跟蹤日期,自動添加時間 follower = models.ForeignKey(UserProfile,verbose_name="跟蹤人") #外鍵 下拉框單選跟蹤人 status_choices = ((1,u"近期無報名計划"), (2,u"2個月內報名"), (3,u"1個月內報名"), (4,u"2周內報名"), (5,u"1周內報名"), (6,u"2天內報名"), (7,u"已報名"), ) status = models.IntegerField(u"狀態",choices=status_choices,help_text=u"選擇客戶此時的狀態") # status = models.IntegerField(u"狀態",choices=get_status_choices_display(),help_text=u"選擇客戶此時的狀態") #報錯 def __unicode__(self): return "%s%s" % (self.customer,self.get_status_display()) def __str__(self): return "%s%s" % (self.customer,self.get_status_display()) #顯示狀態選擇的value-中文 只在return中用get display class Meta: #admin頁面,表名顯示中文 verbose_name = '學員跟蹤記錄表' verbose_name_plural = "學員跟蹤記錄表" #5課程表 class Course(models.Model): name = models.CharField("課程名字",max_length=64,unique=True) #惟一 online_price = models.IntegerField("網絡班價格") offline_price = models.IntegerField("面授班價格") introduction = models.TextField("課程說明") def __unicode__(self): return self.name def __str__(self): return self.name class Meta: #admin頁面,表名顯示中文 verbose_name = '課程表' verbose_name_plural = "課程表" #6班級表 class ClassList(models.Model): course = models.ForeignKey(Course,verbose_name=u"課程") #外鍵 下拉框單選課程 semester = models.IntegerField(verbose_name=u"學期") course_type = models.CharField("課程類型",max_length=64,choices=course_type_choices,default='offline_weekend') #9行 teachers = models.ManyToManyField(UserProfile,verbose_name=u"講師") #多對多 下拉框多選講師 不能顯示在admin的自定義 start_date = models.DateField("開班日期") graduate_date = models.DateField("畢業日期") def __unicode__(self): return "%s(%s)(%s)" %(self.course.name,self.get_course_type_display(),self.semester) def __str__(self): #get display 顯示value 而不是key return "%s(%s)(%s)" %(self.course.name,self.get_course_type_display(),self.semester) class Meta: verbose_name = '班級表' verbose_name_plural = "班級表" unique_together = ('course','semester','course_type') #聯合惟一 課程+學期+類型相同就提示錯誤 #7上課記錄表 class CourseRecord(models.Model): class_obj = models.ForeignKey(ClassList,verbose_name="班級") #外鍵 下拉框單選班級 day_num = models.IntegerField(u"第幾節課") course_date = models.DateField(auto_now_add=True,verbose_name=u"上課時間") teacher = models.ForeignKey(UserProfile,verbose_name="講師") #多對多 下拉框多選講師 #students = models.ManyToManyField(Customer) def __unicode__(self): return "%s[%s]"%(self.class_obj,self.day_num) def __str__(self): return "%s[%s]"%(self.class_obj,self.day_num) class Meta: verbose_name = '上課記錄表' verbose_name_plural = "上課記錄表" unique_together = ('class_obj','day_num') #聯合惟一 班級和第幾節課都相同就報錯(創建記錄的時候) #8學習記錄表(考勤、作業成績) class StudyRecord(models.Model): course_record = models.ForeignKey(CourseRecord,verbose_name="上課記錄") #外鍵 下拉框單選上課記錄 student = models.ForeignKey(Customer,verbose_name="學員") #外鍵 下拉框單選學員 record_choices = (('checked', u"已簽到"), ('late',u"遲到"), ('noshow',u"缺勤"), ('leave_early',u"早退"), ) record = models.CharField(u"簽到狀態", choices=record_choices,max_length=64) score_choices = ((100, 'A+'), (90,'A'), (85,'B+'), (80,'B'), (70,'B-'), (60,'C+'), (50,'C'), (40,'C-'), (0,'D'), (-1,'N/A'), (-100,'COPY'), (-1000,'FAIL'), ) score = models.IntegerField(u"本節成績",choices=score_choices,default=-1) date = models.DateTimeField("日期",auto_now_add=True) note = models.CharField(u"備注",max_length=255,blank=True,null=True) def __unicode__(self): return "%s,%s,%s"%(self.course_record,self.student,self.record) def __str__(self): # return "%s,%s,%s"%(self.course_record,self.student,self.record) return "%s,%s,%s"%(self.course_record,self.student,self.get_record_display()) class Meta: verbose_name = '學習記錄表' verbose_name_plural = "學習記錄表"
admin.py
from django.contrib import admin # Register your models here. from app01 import models # class entryadmin(admin.ModelAdmin): # list_display = ("blog","headline","pub_date","mod_date","n_comments","n_pingbacks") class schooladmin(admin.ModelAdmin): #admin頁面顯示校區表的每個字段 list_display = ("name","city","addr") class UserProfileadmin(admin.ModelAdmin): #admin頁面顯示學校工作人員表-用戶表的每個字段 list_display = ("name","user","school") class Customeradmin(admin.ModelAdmin): #admin頁面顯示學員表-客戶表的某些典型字段 多對多不能寫在這里 list_display = ("qq","name","course","course_type","source_type","referral_from","status","consultant") class CustomerTrackRecordadmin(admin.ModelAdmin): #admin頁面顯示客戶跟蹤記錄表的某些典型字段 list_display = ("customer","track_date","follower","status") class Courseadmin(admin.ModelAdmin): #admin頁面顯示課程表的全部字段 list_display = ("name","online_price","offline_price","introduction") class ClassListadmin(admin.ModelAdmin): #admin頁面顯示班級表的全部字段 多對多不能寫在這里,否則報錯 list_display = ("course","semester","course_type","start_date","graduate_date") class CourseRecordadmin(admin.ModelAdmin): #admin頁面顯示上課記錄表的全部字段 多對多不能寫在這里,否則報錯 list_display = ("class_obj","day_num","course_date") class StudyRecordadmin(admin.ModelAdmin): #admin頁面顯示學習記錄表的全部字段 多對多不能寫在這里,否則報錯 list_display = ("course_record","student","record","score","date","note") admin.site.register(models.School,schooladmin) #自定義字段 注冊后生效 9行 admin.site.register(models.UserProfile,UserProfileadmin) admin.site.register(models.Customer,Customeradmin) admin.site.register(models.CustomerTrackRecord,CustomerTrackRecordadmin) admin.site.register(models.Course,Courseadmin) admin.site.register(models.ClassList,ClassListadmin) admin.site.register(models.CourseRecord,CourseRecordadmin) admin.site.register(models.StudyRecord,StudyRecordadmin)
四、#需求1:將客戶表的數據展示到前端(注意不能用admin,采用bootstrap布局+表格的形式 展示數據)
#需求2:將客戶表中報名字段區分不同的顏色,高亮顯示 custom.html的42行
# 1css中設置自定義的custom.css 2導入到base.html 3class="{{ item.status }
#需求3:給客戶列表添加分頁的功能-簡單的
#需求4:分頁優化-默認顯示5頁(取絕對值,差絕對值小於等於2,就顯示)--baidu
# 前一頁,后一頁來翻頁,到了最后一頁,右箭頭隱藏,到了第一頁,左箭頭隱藏
# 模版不支持abs嗎,就需要simpletag自定義abs函數,自定義函數就實現了前端的html,再load
1、urls
#!/usr/bin/env python #-*- coding:utf-8 -*- __author__ = 'Administrator' from django.conf.urls import url,include from django.contrib import admin from app01 import views urlpatterns = [ url(r'^$', views.dashboard), #app01下都指向dashboard http://127.0.0.1:8000/app01/ url(r'^customers/$', views.customers), # url(r'^Custompager/$', views.Custompager), ]
2、views.py
from django.shortcuts import render from app01 import models from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger #導入用於分頁 # Create your views here. #需求1:將客戶表的數據展示到前端(注意不能用admin,采用bootstrap布局+表格的形式 展示數據) #需求2:將客戶表中報名字段區分不同的顏色,高亮顯示 custom.html的42行 # 1css中設置自定義的custom.css 2導入到base.html 3class="{{ item.status } #需求3:給客戶列表添加分頁的功能-簡單的 #需求4:分頁優化-默認顯示5頁(取絕對值,差絕對值小於等於2,就顯示)--baidu # 前一頁,后一頁來翻頁,到了最后一頁,右箭頭隱藏,到了第一頁,左箭頭隱藏 # 模版不支持abs,就需要simpletag自定義abs函數,自定義函數就實現了前端的html,再load def dashboard(request): return render(request,"app01/dashboard.html") def customers(request): #帶分頁 customer_list = models.Customer.objects.all() #獲取學員表-客戶表的所有記錄 # print(customer_list) paginator = Paginator(customer_list,1) #生成1個分頁的實例,設置每頁有幾條數據 這里是指每頁1條數據 page = request.GET.get("page") #獲取前端的請求 try: customer_objs = paginator.page(page) except PageNotAnInteger: #如果輸入的頁碼不是數字,那么返回第一頁 (首次打開,返回第一頁) customer_objs = paginator.page(1) except EmptyPage: #如果輸入的頁碼超出頁碼范圍(例如,一共是3頁,輸入的是5),就返回最后一頁 customer_objs = paginator.page(paginator.num_pages) #num_pages指頁碼總數 # return render(request,"app01/custom.html",{"customer_list":customer_list}) return render(request,"app01/custom.html",{"customer_list":customer_objs}) # def customers1(request): # customer_list1 = models.Customer.objects.all() # return render(request,"app01/custom.html",{"customer_list":customer_list1})
3、custom.html
{% extends "base.html" %} {% load custom_tags %} {#加載自定義的函數--simpletags#} {% block header %} old boy crm {% endblock %} {% block content %} {# {{ customer_list }}#} 客戶信息列表 {% endblock %} {% block content-page %} {# {{ customer_list }}#} {# haha22#} <table class="table table-hover"> {# http://v3.bootcss.com/css/#tables 布局(起步)和表格(全局css樣式)直接在bootstrap3中找#} <thead> <tr> <th>ID</th> <th>QQ</th> <th>姓名</th> <th>渠道</th> <th>咨詢課程</th> <th>課程類型</th> <th>客戶備注</th> <th>狀態</th> <th>課程顧問</th> <th>日期</th> </tr> </thead> <tbody> {% for item in customer_list %} <tr> <td>{{ item.id }}</td> <td>{{ item.qq }}</td> <td>{{ item.name }}</td> <td>{{ item.source_type }}</td> <td>{{ item.course }}</td> <td>{{ item.get_course_type_display }}</td> {# 取value的值 get display#} <td>{{ item.consult_memo|truncatechars:10 }}</td> {# 備注取前10個字符#} {# <td class="{{ item.status }}">{{ item.get_status_display }}</td>#} {# 取value的值 get display 1css中設置自定義的custom.css 2導入到base.html 3class="{{ item.status }}#} {# 根據不同的狀態,設置不同的顏色#} <td class="{{ item.status }}">{{ item.status|alex_upper }}</td> {# 取的是key,將狀態key的字母全部轉換成大寫 |alex_upper 這里的alex_upper是自定義函數名 注意生效需要手動重啟#} {# 將item.status作為參數傳到函數alex_upper 只傳入了1個參數#} <td>{{ item.consultant }}</td> <td>{{ item.date }}</td> </tr> {% endfor %} </tbody> </table> <div class="pagination"> {# 分頁優化版,從bootstrap找的,進行修改#} <nav> <ul class="pagination"> {% if customer_list.has_previous %} <li class=""><a href="?page={{ customer_list.previous_page_number }}" aria-label="Previous"><span aria-hidden="true">«</span></a></li> {% endif %} {# 左箭頭 前一頁 判斷有沒有上一頁#} {% for i in customer_list.paginator.page_range %} {# 遍歷讓每一頁都顯示#} {% guess_page customer_list.number i %} {# 這個語句調用自定義的simple_tags 如果很多頁面都需要分頁 就服用simple_tags#} {# 考慮在后台simpl_tags中返回html元素 customer_list.number 拼寫#} {# {% if i == customer_list.number %}#} {# 當前頁,高亮顯示#} {# <li class="active"><a href="?page={{ i }}">{{ i }} </a></li>#} {# {% else %}#} {# 非當前頁,取消高亮顯示#} {# <li class=""><a href="?page={{ i }}">{{ i }} </a></li>#} {# {% endif %}#} {% endfor %} {# 頁碼#} {% if customer_list.has_next %} <li class=""><a href="?page={{ customer_list.next_page_number }}" aria-label="next"><span aria-hidden="true">»</span></a></li> {# 右箭頭 后一頁 判斷有沒有下一頁 沒有下一頁,就不顯示右箭頭#} {% endif %} </ul> </nav> {# 分頁簡易版#} <span class="step-links"> {% if customer_list.has_previous %} <a href="?page={{ customer_list.previous_page_number }}">previous</a> {% endif %} {# 分頁的前端代碼,前一頁#} <span class="current"> Page {{ customer_list.number }} of {{ customer_list.paginator.num_pages }}. </span> {# 當前頁 page 當前頁 of 總頁碼#} {% if customer_list.has_next %} <a href="?page={{ customer_list.next_page_number }}">next</a> {% endif %} {# 下一頁#} </span> </div> {% endblock %}
4、simple_tags(custom_tags)
#!/usr/bin/env python #-*- coding:utf-8 -*- __author__ = 'Administrator' #自定義標簽語法,用於轉換成大小寫 from django import template #導入 from django.utils.html import format_html #用這個將后端return的字符串轉換成html register = template.Library() #注冊到語法庫 @register.filter #裝飾器 def alex_lower(value): #轉換成小寫 只能傳入一個參數 return value.lower() @register.filter def alex_upper(value): #轉換成大寫 print("alex_upper",value) #alex_upper unregistered return value.upper() @register.simple_tag def guess_page(current_page,loop_num): #simple_tag 可以傳入2個參數 # {% if i == customer_list.number %} # {# 當前頁,高亮顯示#} # <li class="active"><a href="?page={{ i }}">{{ i }} </a></li> # {% else %} # {# 非當前頁,取消高亮顯示#} # <li class=""><a href="?page={{ i }}">{{ i }} </a></li> # {% endif %} #翻譯成后端的python語言 offset = abs(current_page-loop_num) if offset <=1: #判斷顯示3頁,前后各1頁,3頁之外的不顯示 if current_page == loop_num: #當前頁高亮 page_ele = """<li class="active"><a href="?page=%s">%s</a></li>""" % (loop_num,loop_num) # 3引號的位置 loop_num 拼寫 else: #非當前頁不高亮 page_ele = """<li class=""><a href="?page=%s">%s</a></li>""" % (loop_num,loop_num) return format_html(page_ele) #后端return的字符串轉換成html # return page_ele else: return "" #去掉前端的None