销售员/学员/讲师系统
前言: 今晚寫(xiě)一篇關(guān)于學(xué)員/講師/銷(xiāo)售員CRM系統(tǒng)。這個(gè)小項(xiàng)目是27號(hào)開(kāi)始做的,大概搞了一星期不到。我把一些知識(shí)點(diǎn)總結(jié)下,還寫(xiě)下當(dāng)時(shí)克服的BUG。
?
Django練習(xí)小項(xiàng)目:學(xué)員管理系統(tǒng)設(shè)計(jì)開(kāi)發(fā)
帶著項(xiàng)目需求學(xué)習(xí)是最有趣和效率最高的,今天就來(lái)基于下面的需求來(lái)繼續(xù)學(xué)習(xí)Django?
項(xiàng)目需求:
拿到需求后,先要分析,再設(shè)計(jì)表結(jié)構(gòu): 超級(jí)重要!!
1 from django.db import models 2 3 from django.contrib.auth.models import User #django自帶的用戶認(rèn)證表 4 # Create your models here. 5 course_type_choice = (("online", u"網(wǎng)絡(luò)班"), 6 ("offline_weekend", u"面授班(周末)"), 7 ("offline_fulltime", u"面授班(脫產(chǎn))"), 8 ) # 課程類(lèi)型 9 10 class School(models.Model): #學(xué)校表 11 name = models.CharField(max_length=128, unique=True) 12 city = models.CharField(max_length=64) 13 addr = models.CharField(max_length=128) 14 15 def __str__(self): #給前端界面顯示學(xué)校名 16 return self.name 17 18 19 class UserProfile(models.Model): #內(nèi)部員工表 20 # User是一張表,在UserProfile關(guān)聯(lián)User表,類(lèi)似繼承User表,也可以拓展別的字段 21 # 這里不能用ForeignKey(一對(duì)多),比如User表里有一個(gè)zcl, 22 # 用FK,則可以在UserProfile創(chuàng)建多個(gè)zcl用戶,實(shí)際上UserProfile應(yīng)當(dāng)只有一個(gè)用戶 23 # 用OneToOne關(guān)聯(lián),只能有一個(gè)UserProfile用戶與User關(guān)聯(lián),其它用戶不能關(guān)聯(lián), 24 # 在數(shù)據(jù)庫(kù)層面OneToOne與ForeignKey實(shí)現(xiàn)是相同的,都是用FK, OneToOne是django admin層面做限制的 25 user = models.OneToOneField(User,verbose_name=u"登陸用戶名") 26 name = models.CharField(max_length=64, verbose_name=u"全名") 27 school = models.ForeignKey("School") #比如領(lǐng)導(dǎo)可以管理多個(gè)學(xué)校,但有些老師就只能對(duì)應(yīng)一個(gè)學(xué)校 28 user_type_choice = (("salespeople", u"銷(xiāo)售員"), 29 ("teachers", u"講師"), 30 ("others", u"其它"), 31 ) 32 user_type = models.CharField(verbose_name=u"用戶類(lèi)型",max_length=64, choices=user_type_choice, default="others") 33 34 def __str__(self): 35 return self.name 36 37 class Meta: 38 # 加上權(quán)限。can_del_customer是存在數(shù)據(jù)庫(kù)中的,"可以刪除用戶"是顯示在界面的 39 # permissions = (("can_del_customer",u"可以刪除用戶"),) 40 # 加入三條權(quán)限 41 permissions = (("view_customer_list",u"可以查看客戶列表"), # 對(duì)銷(xiāo)售員的權(quán)限 42 ("view_customer_info", u"可以查看客戶詳情"), 43 ("edit_own_customer_info", u"可以修改自己的客戶信息"), 44 45 ("view_class_list", u"可以查看班級(jí)列表"), # 對(duì)講師的權(quán)限 46 ("view_class_info", u"可以查看班級(jí)詳情"), 47 ("edit_own_class_info", u"可以修改自己的班級(jí)信息"), 48 49 ) 50 51 52 class CustomerTrackRecord(models.Model): #客戶跟蹤記錄表 53 customer = models.ForeignKey("Customer") #一個(gè)客戶可有多個(gè)跟蹤記錄 54 track_record = models.TextField(u"跟蹤記錄") 55 track_date = models.DateField(auto_now_add=True) #跟蹤日期 56 tracker = models.ForeignKey(UserProfile) #一條跟蹤記錄只能有一個(gè)追蹤人 57 status_choices = ((1, u"近期無(wú)報(bào)名計(jì)劃"), 58 (2, u"2個(gè)月內(nèi)報(bào)名"), 59 (3, u"1個(gè)月內(nèi)報(bào)名"), 60 (4, u"2周內(nèi)報(bào)名"), 61 (5, u"1周內(nèi)報(bào)名"), 62 (6, u"2天內(nèi)報(bào)名"), 63 (7, u"已報(bào)名"), 64 ) 65 status = models.IntegerField(u"狀態(tài)",choices=status_choices,help_text=u"選擇客戶此時(shí)的狀態(tài)") 66 67 def __str__(self): 68 return self.customer.qq 69 70 71 class Course(models.Model): #課程表 72 name = models.CharField(max_length=64, unique=True) #課程名 73 online_price = models.IntegerField() #網(wǎng)絡(luò)班課程價(jià)格 74 offline_price = models.IntegerField() #面授班課程價(jià)格 75 introduction = models.TextField() #課程介紹 76 77 def __str__(self): 78 return self.name 79 80 81 class ClassList(models.Model): # 班級(jí)表 82 course = models.ForeignKey(Course, verbose_name=u"課程") # 關(guān)聯(lián)課程表 83 semester = models.IntegerField(verbose_name=u"學(xué)期") 84 teachers = models.ManyToManyField(UserProfile, verbose_name=u"講師") # 多對(duì)多關(guān)聯(lián) 85 start_date = models.DateField(verbose_name=u"開(kāi)班日期") # 開(kāi)班日期 86 graduate_date = models.DateField(blank=True,null=True) # 結(jié)業(yè)日期 87 # 課程類(lèi)型 88 course_type = models.CharField(max_length=64, choices=course_type_choice,default="offline_weekend") 89 90 def __str__(self): 91 return "%s[%s期][%s]" % (self.course, self.semester, self.get_course_type_display()) 92 93 class Meta: 94 # 聯(lián)合唯一,python網(wǎng)絡(luò)班15期只能有一個(gè) 95 unique_together = ("course", "semester", "course_type") 96 97 98 class Customer(models.Model): # 學(xué)員表 99 qq = models.CharField(max_length=64, unique=True) 100 # 名字可為空,剛來(lái)咨詢時(shí)不會(huì)告訴name 101 name = models.CharField(max_length=64, blank=True, null=True) 102 phone = models.BigIntegerField(blank=True, null=True) # 不用IntegerField,不夠長(zhǎng) 103 course = models.ForeignKey("Course") # 學(xué)員咨詢的課程,只記錄咨詢的一個(gè)課程,若有多個(gè)可備注說(shuō)明 104 course_type = models.CharField(verbose_name=u"課程類(lèi)型", max_length=64, choices=course_type_choice, default="offline_weekend") 105 consult_memo = models.TextField(verbose_name=u"咨詢備注") # 咨詢內(nèi)容 106 source_type_choice = (("qq", u"qq群"), 107 ("referral", u"內(nèi)部轉(zhuǎn)介紹"), 108 ("51CTO", u"51CTO"), 109 ("agent", u"招生代理"), 110 ("others", u"其它"), 111 ) #客戶來(lái)源 112 source_type = models.CharField(max_length=64, choices=source_type_choice, default="others") 113 # 表示自關(guān)聯(lián)(Customer表關(guān)聯(lián)Customer表),也可用referral_from = models.ForeignKey("Customer") 114 # 1.加上self 2.自關(guān)聯(lián)要加上related_name,通過(guò)internal_referral反查數(shù)據(jù) 115 # 反向關(guān)聯(lián)得加上related_name: eg:A介紹B來(lái)上課,對(duì)A通過(guò)referral_from可找到B;反之需通過(guò)referral 116 # 該字段表示該學(xué)生被誰(shuí)介紹來(lái)上課的 117 referral_from = models.ForeignKey("self", blank=True, null=True, related_name="referral") 118 119 status_choices = (("singed", u"已報(bào)名"), 120 ("unregistered", u"未報(bào)名"), 121 ("graduated", u"已畢業(yè)"), 122 ("drop_off", u"退學(xué)"), 123 ) # 客戶來(lái)源 124 status = models.CharField(max_length=64, choices=status_choices, default="unregistered") 125 consultant = models.ForeignKey("UserProfile", verbose_name="課程顧問(wèn)") 126 date = models.DateField(u"咨詢?nèi)掌?/span>", auto_now_add=True) # auto_now_add創(chuàng)建時(shí)自動(dòng)添加當(dāng)前日期 127 class_list = models.ManyToManyField("ClassList", blank=True) # 對(duì)于多對(duì)多字段,不需要null=true 128 129 def __str__(self): 130 return "%s[%s]" % (self.qq, self.name) 131 132 133 class CourseRecord(models.Model): # 上課記錄表 134 class_obj = models.ForeignKey(ClassList) # 關(guān)聯(lián)班級(jí) 135 day_num = models.IntegerField(u"第幾節(jié)課") 136 course_date = models.DateField(auto_now_add=True, verbose_name=u"上課時(shí)間") 137 teacher = models.ForeignKey(UserProfile) # 講師 138 139 # students = models.ManyToManyField(Customer) 不能在這里多對(duì)多,if do this,can't 查看出勤情況 140 def __str__(self): 141 return "%s[day%s]" % (self.class_obj, self.day_num) 142 143 class Meta: # 聯(lián)合唯一 python自動(dòng)化12期網(wǎng)絡(luò)班 12;只能有一個(gè)12天 144 unique_together = ("class_obj", "day_num") 145 146 147 class StudyRecord(models.Model): 148 # 關(guān)聯(lián)上課記錄表,上課記錄表有第幾節(jié)課字段,同時(shí)也與ClassList關(guān)聯(lián),可知道是哪個(gè)班第幾期 149 course_record = models.ForeignKey(CourseRecord) 150 student = models.ForeignKey(Customer) # 關(guān)聯(lián)學(xué)員表 151 record_choices = (('checked', u"已簽到"), 152 ('late',u"遲到"), 153 ('no_show',u"缺勤"), 154 ('leave_early',u"早退"), 155 ) 156 record = models.CharField(u"狀態(tài)", choices=record_choices,default="no_show",max_length=64) 157 score_choices = ((100, 'A+'), 158 (90,'A'), 159 (85,'B+'), 160 (80,'B'), 161 (70,'B-'), 162 (60,'C+'), 163 (50,'C'), 164 (40,'C-'), 165 (0,'D'), 166 (-1,'N/A'), # 暫無(wú)成績(jī) 167 (-100,'COPY'), 168 (-1000,'FAIL'), 169 ) 170 score = models.IntegerField(u"本節(jié)成績(jī)",choices=score_choices,default=-1) 171 date = models.DateTimeField(auto_now_add=True) 172 note = models.CharField(u"備注",max_length=255,blank=True,null=True) 173 174 def __str__(self): 175 return "%s,%s,%s" % (self.course_record,self.student,self.get_record_display()) View Code?
先來(lái)張圖看看效果: 下圖是銷(xiāo)售員Alex登陸后看到的界面
點(diǎn)擊右上方Alex已招學(xué)員,出現(xiàn)下圖界面:
?
一、前端界面實(shí)現(xiàn)
界面看著我感覺(jué)是蠻漂亮的,登陸界面和信息界面都是搞bootstrap模版的。只要將bootstrap模版修改下,就變成所需要的界面啦。不會(huì)修改的可以看看如何使用bootstrap。
?
二、字?jǐn)?shù)顯示限制
如果備注過(guò)多,會(huì)使界面不好看,要想使備注只顯示一定的字?jǐn)?shù),可用下列方法:?只顯示13個(gè)字節(jié)
<td>{{ customer.consult_memo|truncatechars:13}}</td>?
三、報(bào)名狀態(tài)加色
第一種方法,比較麻煩,有興趣可看django進(jìn)階-modelform&admin action
第二種方法更簡(jiǎn)單
1. 在bootstrap添加自定義的css樣式文件,custom.css
2. 在基礎(chǔ)模版(我定義的是base.html,其它html模塊是繼承它的)導(dǎo)入custom.css文件:
<link href="/static/bootstrap-3.3.7-dist/css/custom.css" rel="stylesheet">3. 你隨意在custom.css定義樣式
.singed{background-color:yellow; }.unregistered{background-color:#ff6664; }.graduated{background-color:#32ff0a; }.drop_off{background-color:bisque; } View Code4. 在對(duì)應(yīng)的customer.html的標(biāo)簽加入樣式; customer.status是后臺(tái)傳給前端的,是學(xué)生的報(bào)名狀態(tài)。
<td class="{{ customer.status }}">{{ customer.get_status_display }}</td>
四、分頁(yè)功能
其實(shí)Alex銷(xiāo)售員登陸后看到的界面只有兩條客戶的信息,這是我在后臺(tái)寫(xiě)的。注意看左下角有個(gè)分頁(yè),類(lèi)似與百度搜索的分頁(yè)。其實(shí)分頁(yè)實(shí)現(xiàn)起來(lái)還是有點(diǎn)難度的。
先看django官方文檔。官方文檔寫(xiě)得很詳細(xì)!!
>>> from django.core.paginator import Paginator >>> objects = ['john', 'paul', 'george', 'ringo'] >>> p = Paginator(objects, 2) >>> p.count 4 >>> p.num_pages 2 >>> type(p.page_range) # `<type 'rangeiterator'>` in Python 2. <class 'range_iterator'> >>> p.page_range range(1, 3) >>> page1 = p.page(1) >>> page1 <Page 1 of 2> >>> page1.object_list ['john', 'paul'] >>> page2 = p.page(2) >>> page2.object_list ['george', 'ringo'] >>> page2.has_next() False >>> page2.has_previous() True >>> page2.has_other_pages() True >>> page2.next_page_number() Traceback (most recent call last): ... EmptyPage: That page contains no results >>> page2.previous_page_number() 1 >>> page2.start_index() # The 1-based index of the first item on this page 3 >>> page2.end_index() # The 1-based index of the last item on this page 4 >>> p.page(0) Traceback (most recent call last): ... EmptyPage: That page number is less than 1 >>> p.page(3) Traceback (most recent call last): ... EmptyPage: That page contains no results View Code后臺(tái)實(shí)現(xiàn):
1 def customers(request): 2 print(">>>>request:",request) 3 # 查找所有客戶,獲取所有信息的結(jié)果集,但并不是所有信息都已經(jīng)取出來(lái)了(如果有上萬(wàn)條數(shù)據(jù),不能一次性取出來(lái),先取一部分), 4 customer_list = models.Customer.objects.all() 5 print(">>>>customers:", customer_list) 6 paginator = Paginator(customer_list, 2) # 生成分頁(yè)實(shí)例: 每一頁(yè)有兩條數(shù)據(jù) 7 page = request.GET.get("page") # 獲取前端點(diǎn)擊的頁(yè)數(shù),參數(shù)page可自定義 8 try: 9 customer_objs = paginator.page(page) # 生成第page頁(yè)的對(duì)象 10 except PageNotAnInteger: 11 # If page is not an integer, deliver first page 12 # 如果輸入的頁(yè)碼不是下標(biāo),則返回第一頁(yè) 13 customer_objs = paginator.page(1) 14 except EmptyPage: 15 # If page is out of range (e.g. 9999), deliver last page of results. 16 # 如果輸入的頁(yè)碼超出,則跳轉(zhuǎn)到最后的頁(yè)碼 17 customer_objs = paginator.page(paginator.num_pages) 18 19 return render(request, "crm/customer.html", {"customer_list": customer_objs})前端實(shí)現(xiàn):
1 <div class="pagination"> 2 3 <nav> 4 <ul class="pagination"> 5 {% if customer_list.has_previous %} 6 <li class=""><a href="?page={{ customer_list.previous_page_number }}" aria-label="Previous"><span aria-hidden="true">«</span></a></li> 7 {% endif %} 8 9 {% for page_num in customer_list.paginator.page_range %} 10 <!-- abs_page為函數(shù)名,后兩個(gè)為參數(shù) --> 11 {% abs_page customer_list.number page_num %} 12 13 {% endfor %} 14 15 {% if customer_list.has_next %} 16 <li class=""><a href="?page={{ customer_list.next_page_number }}" aria-label="Next"><span aria-hidden="true">»</span></a></li> 17 {% endif %} 18 </ul> 19 </nav> 20 21 </div>第一次進(jìn)入http://127.0.0.1:8000/crm/customer/頁(yè)面時(shí),請(qǐng)求為get方式,后臺(tái)接收到的page參數(shù)為空,故會(huì)出PagenotAnInterger異常,故會(huì)返回到第一頁(yè)!!
注意前端的第九行代碼:?customer_list.paginator.page_range是頁(yè)數(shù)的范圍。customer_list只是一個(gè)第幾頁(yè)的實(shí)例而已,是無(wú)法獲取到頁(yè)數(shù)的范圍的。
但是問(wèn)題來(lái)了,如果,你有100條數(shù)據(jù),每頁(yè)只放兩條數(shù)據(jù),意味著界面得有50個(gè)button,基本上頁(yè)面是放不下的。
如果頁(yè)面過(guò)多,看下百度怎么處理:
可用abs絕對(duì)值,若當(dāng)前頁(yè)面為第6頁(yè),想讓3、4、5和7、8、9也顯示出來(lái),可在循環(huán)判斷頁(yè)面時(shí),利用abs, 當(dāng)|循環(huán)的頁(yè)面值-當(dāng)前的頁(yè)面值|<=3 ,則顯示。
但問(wèn)題又來(lái)了,前端的templates可沒(méi)有abs取絕對(duì)值這種后臺(tái)才有的方法,怎么辦??
?
自定義template tags
https://docs.djangoproject.com/es/1.9/howto/custom-template-tags/?
效果圖:
??
后臺(tái)是如何自定義模版??
首先自定義templates模版,我隨便建了個(gè)文件custom_tags.py,必須放在新建包templatetags下:
custom_tags.py: 當(dāng)頁(yè)碼絕對(duì)值之差小于3時(shí),則返回頁(yè)碼按鈕的html給前端,反之不返回。
1 from?django?import?template 2 from?django.utils.html?import?format_html 3 ? 4 register?=?template.Library()??#django的語(yǔ)法庫(kù) 5 6 ? 7 @register.simple_tag 8 def?abs_page(current_page, loop_page): 9 ????offset?=?abs(current_page?-?loop_page) 10 ????if?offset <?3: 11 ????????if?current_page?==?loop_page: 12 ????????????page_ele?=?"<li class='active'><a href='?page=%s'>%s</a></li>"?%?(current_page, current_page) 13 ????????else: 14 ????????????page_ele?=?"<li class=''><a href='?page=%s'>%s</a></li>"?%?(loop_page, loop_page) 15 ????????return?format_html(page_ele)??#將字符串轉(zhuǎn)化為html,返回給前端 16 ????else: 17 ????????return?""?
五、modelform進(jìn)階
modelform之前有寫(xiě)過(guò),django進(jìn)階-modelform&admin action, 但主要是寫(xiě)django自帶的admin。
現(xiàn)在我有個(gè)需求,銷(xiāo)售員Alex想查看客戶的詳細(xì)信息。只需只擊客戶的ID號(hào),便可查看,當(dāng)然也可以修改。
前端:
<td><a href="/crm/customers/{{customer.id}}/">{{customer.id}}</a></td>urls:
# 當(dāng)學(xué)員id當(dāng)作參數(shù),傳給customer_detail方法 url(r'^customers/(\d+)/$', views.customer_detail),后臺(tái):
def customer_detail(request,customer_id):customer_obj = models.Customer.objects.get(id=customer_id)form = forms.CustomerModelForm()return render(request,"crm/customer_detail.html",{"customer_form":form})看前端界面顯示:?雖然能顯示出表單,但無(wú)法顯示出學(xué)員的信息,而且太丑了!!
如何顯示出學(xué)員的信息:
customer_obj = models.Customer.objects.get(id=customer_id)form = forms.CustomerModelForm(instance=customer_obj) # 將數(shù)據(jù)對(duì)象當(dāng)作參數(shù)傳入如何使前端界面更漂亮:
forms.py表單文件:
1 from django.forms import Form,ModelForm 2 from CRM import models 3 4 5 # 客戶的form表單,可用于修改客戶的信息,增加客戶的前端界面 6 class CustomerModelForm(ModelForm): 7 8 class Meta: 9 model = models.Customer # 綁定Customer表 10 exclude = () 11 12 # 重構(gòu)modelform的初始化類(lèi)的方式;前面已經(jīng)繼承modelform,下面進(jìn)行重構(gòu) 13 def __init__(self, *args, **kwargs): 14 super(CustomerModelForm, self).__init__(*args, **kwargs) 15 16 for field_name in self.base_fields: 17 field = self.base_fields[field_name] # 循環(huán)取出所有字段 18 field.widget.attrs.update({"class": "form-control"}) # 給字段加上樣式 View Code前端:?樣式是從bootstrap參考來(lái)的
1 {% block page_content %} 2 <!-- action為空表示數(shù)據(jù)提交到當(dāng)前url --> 3 <form class="form-horizontal" method="post" action="">{% csrf_token %} 4 {% for field in customer_form %} 5 <div class="form-group"> 6 {% if field.field.required %} <!--若是必填字段 --> 7 <label class="col-sm-2 control-label"> 8 <span style="color: red;font-size: larger">*</span>{{ field.label }} 9 </label> 10 {% else %} <!-- label在django默認(rèn)為加粗 --> 11 <label style="font-weight: normal" class="col-sm-2 control-label">{{ field.label }}</label> 12 {% endif %} 13 <div class="col-sm-8"> 14 {{ field }} 15 {% if field.errors %} <!--錯(cuò)誤提示modelform已經(jīng)幫我們封裝好了--> 16 <ul> 17 {% for error in field.errors %} 18 <li style="color: red">{{ error }}</li> 19 {% endfor %} 20 </ul> 21 {% endif %} 22 </div> 23 </div> 24 {% endfor %} 25 <div class="col-md-10"> 26 <button type="submit" class="btn btn-success pull-right">Save</button> 27 </div> 28 </form> 29 30 {% endblock %} View Code效果圖:
修改后保存信息
1 def customer_detail(request,customer_id): 2 #通過(guò)modelform顯示某用戶的詳細(xì)信息,修改后可保存 3 customer_obj=models.Customer.objects.get(id=customer_id) 4 if request.method=="POST": 5 #必須加instance=customer_obj告訴修改哪條數(shù)據(jù),否則就是創(chuàng)建數(shù)據(jù)了 6 form=forms.CustomerModelForm(request.POST,instance=customer_obj) 7 if form.is_valid(): 8 form.save()#修改后保存 9 else: 10 form=forms.CustomerModelForm(instance=customer_obj) 11 return render(request,"crm/customer_detail.html",{"customer_form":form}) View Code?
六、必填與非必填字段
效果圖:?必填字段有加粗,且左上角有紅色*號(hào)
只需修改下前端代碼即可:
1 {% if field.field.required %} <!--若是必填字段 --> 2 <label class="col-sm-2 control-label"> 3 <span style="color: red;font-size: larger">*</span>{{ field.label }} 4 </label> 5 {% else %} <!-- label在django默認(rèn)為加粗 --> 6 <label style="font-weight: normal" class="col-sm-2 control-label">{{ field.label }}</label> 7 {% endif %}?
權(quán)限分配, 這個(gè)改天再寫(xiě)博客整理下:?三個(gè)角色的權(quán)限是不同的。對(duì)銷(xiāo)售員來(lái)講,無(wú)法修改非本人招收客戶的信息。
?
七、url別名
啥是url別名??
1 #當(dāng)學(xué)員id當(dāng)作參數(shù),傳給customer_detail方法, 2 #給該url起別名,一調(diào)用別名customer_detail,就關(guān)聯(lián)上url 3 url(r'^customers/(\d+)/$',views.customer_detail,name="customer_detail"),現(xiàn)在銷(xiāo)售員想查看客戶的詳細(xì)信息,只需一點(diǎn)擊客戶的ID號(hào)便可查看。so, ID號(hào)必須是個(gè)a標(biāo)簽,下面來(lái)看看前端實(shí)現(xiàn):
1 <!-- 這里查看學(xué)員的詳細(xì)信息不應(yīng)該寫(xiě)列,否則當(dāng)url一改變,得來(lái)這里改代碼 --> 2 <!-- <td><a href = " /crm/customers/ {{customer.id}} / "> {{ customer.id }} </a></td> --> 3 4 <td><a href = "{% url 'customer_detail' customer.id %}"> {{ customer.id }} </a></td>注意了,如果不用url別名的話,就用第2行代碼。但是,這樣項(xiàng)目的可維護(hù)性大大降低了。當(dāng)你需改動(dòng)url時(shí),必須到前端修改對(duì)應(yīng)的a標(biāo)簽。如果用了url別名,就不用再來(lái)前端修改了。
看到?jīng)],我用瀏覽器審查元素,瀏覽器已經(jīng)自動(dòng)將ID號(hào)的a標(biāo)簽,轉(zhuǎn)化為一條url. 神奇!!
?
轉(zhuǎn)載于:https://www.cnblogs.com/0zcl/p/6664810.html
總結(jié)
以上是生活随笔為你收集整理的销售员/学员/讲师系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【bzoj1263】[SCOI2006]
- 下一篇: windows 删除删除不掉的文件