crm 使用stark組件
阿新 • • 發佈:2018-03-22
star customer 外鍵關聯 設置 slist 重點大學 其中 content 對象
# Create your models here. from django.db import models class Department(models.Model): """ 部門表 市場部 1000 銷售 1001 """ title = models.CharField(verbose_name=‘部門名稱‘, max_length=16) code = models.IntegerField(verbose_name=‘部門編號‘, unique=True, null=False) def __str__(self): return self.title class UserInfo(models.Model): """ 員工表 """ name = models.CharField(verbose_name=‘員工姓名‘, max_length=16) username = models.CharField(verbose_name=‘用戶名‘, max_length=32) password = models.CharField(verbose_name=‘密碼‘, max_length=64) email = models.EmailField(verbose_name=‘郵箱‘, max_length=64) depart = models.ForeignKey(verbose_name=‘部門‘, to="Department", to_field="code") def __str__(self): return self.name class Course(models.Model): """ 課程表 如: Linux基礎 Linux架構師 Python自動化開發精英班 Python自動化開發架構師班 Python基礎班 go基礎班 """ name = models.CharField(verbose_name=‘課程名稱‘, max_length=32) def __str__(self): return self.name class School(models.Model): """ 校區表 如: 北京海澱校區 上海校區 """ title = models.CharField(verbose_name=‘校區名稱‘, max_length=32) def __str__(self): return self.title class ClassList(models.Model): """ 班級表 如: Python全棧 面授班 5期 10000 2017-11-11 2018-5-11 """ school = models.ForeignKey(verbose_name=‘校區‘, to=‘School‘) course = models.ForeignKey(verbose_name=‘課程名稱‘, to=‘Course‘) semester = models.IntegerField(verbose_name="班級(期)") price = models.IntegerField(verbose_name="學費") start_date = models.DateField(verbose_name="開班日期") graduate_date = models.DateField(verbose_name="結業日期", null=True, blank=True) memo = models.CharField(verbose_name=‘說明‘, max_length=256, blank=True, null=True, ) # teachers = models.ManyToManyField(verbose_name=‘任課老師‘, to=‘UserInfo‘,limit_choices_to={‘depart_id__in‘:[1003,1004],}) teachers = models.ManyToManyField(verbose_name=‘任課老師‘, to=‘UserInfo‘, limit_choices_to={"depart_id__in": [1002, 1003]}, related_name="abc") tutor = models.ForeignKey(verbose_name=‘班主任‘, to=‘UserInfo‘, limit_choices_to={"depart_id": 1001}, related_name=‘classes‘) def __str__(self): return "{0}({1}期)".format(self.course.name, self.semester) class Customer(models.Model): """ 客戶表 """ qq = models.CharField(verbose_name=‘qq‘, max_length=64, unique=True, help_text=‘QQ號必須唯一‘) name = models.CharField(verbose_name=‘學生姓名‘, max_length=16) gender_choices = ((1, ‘男‘), (2, ‘女‘)) gender = models.SmallIntegerField(verbose_name=‘性別‘, choices=gender_choices) education_choices = ( (1, ‘重點大學‘), (2, ‘普通本科‘), (3, ‘獨立院校‘), (4, ‘民辦本科‘), (5, ‘大專‘), (6, ‘民辦專科‘), (7, ‘高中‘), (8, ‘其他‘) ) education = models.IntegerField(verbose_name=‘學歷‘, choices=education_choices, blank=True, null=True, ) graduation_school = models.CharField(verbose_name=‘畢業學校‘, max_length=64, blank=True, null=True) major = models.CharField(verbose_name=‘所學專業‘, max_length=64, blank=True, null=True) experience_choices = [ (1, ‘在校生‘), (2, ‘應屆畢業‘), (3, ‘半年以內‘), (4, ‘半年至一年‘), (5, ‘一年至三年‘), (6, ‘三年至五年‘), (7, ‘五年以上‘), ] experience = models.IntegerField(verbose_name=‘工作經驗‘, blank=True, null=True, choices=experience_choices) work_status_choices = [ (1, ‘在職‘), (2, ‘無業‘) ] work_status = models.IntegerField(verbose_name="職業狀態", choices=work_status_choices, default=1, blank=True, null=True) company = models.CharField(verbose_name="目前就職公司", max_length=64, blank=True, null=True) salary = models.CharField(verbose_name="當前薪資", max_length=64, blank=True, null=True) source_choices = [ (1, "qq群"), (2, "內部轉介紹"), (3, "官方網站"), (4, "百度推廣"), (5, "360推廣"), (6, "搜狗推廣"), (7, "騰訊課堂"), (8, "廣點通"), (9, "高校宣講"), (10, "渠道代理"), (11, "51cto"), (12, "智匯推"), (13, "網盟"), (14, "DSP"), (15, "SEO"), (16, "其它"), ] source = models.SmallIntegerField(‘客戶來源‘, choices=source_choices, default=1) referral_from = models.ForeignKey( ‘self‘, blank=True, null=True, verbose_name="轉介紹自學員", help_text="若此客戶是轉介紹自內部學員,請在此處選擇內部學員姓名", related_name="internal_referral" ) course = models.ManyToManyField(verbose_name="咨詢課程", to="Course") status_choices = [ (1, "已報名"), (2, "未報名") ] status = models.IntegerField( verbose_name="狀態", choices=status_choices, default=2, help_text=u"選擇客戶此時的狀態" ) consultant = models.ForeignKey(verbose_name="課程顧問", to=‘UserInfo‘, related_name=‘consultanter‘, limit_choices_to={‘depart_id‘: 1001}) date = models.DateField(verbose_name="咨詢日期", auto_now_add=True) recv_date = models.DateField(verbose_name="當前課程顧問的接單日期", null=True) last_consult_date = models.DateField(verbose_name="最後跟進日期", ) def __str__(self): return "姓名:{0},QQ:{1}".format(self.name, self.qq, ) class ConsultRecord(models.Model): """ 客戶跟進記錄 """ customer = models.ForeignKey(verbose_name="所咨詢客戶", to=‘Customer‘) consultant = models.ForeignKey(verbose_name="跟蹤人", to=‘UserInfo‘) date = models.DateField(verbose_name="跟進日期", auto_now_add=True) note = models.TextField(verbose_name="跟進內容...") def __str__(self): return self.customer.name + ":" + self.consultant.name class PaymentRecord(models.Model): """ 繳費記錄 """ customer = models.ForeignKey(Customer, verbose_name="客戶") class_list = models.ForeignKey(verbose_name="班級", to="ClassList", blank=True, null=True) pay_type_choices = [ (1, "訂金/報名費"), (2, "學費"), (3, "轉班"), (4, "退學"), (5, "退款"), ] pay_type = models.IntegerField(verbose_name="費用類型", choices=pay_type_choices, default=1) paid_fee = models.IntegerField(verbose_name="費用數額", default=0) turnover = models.IntegerField(verbose_name="成交金額", blank=True, null=True) quote = models.IntegerField(verbose_name="報價金額", blank=True, null=True) note = models.TextField(verbose_name="備註", blank=True, null=True) date = models.DateTimeField(verbose_name="交款日期", auto_now_add=True) consultant = models.ForeignKey(verbose_name="負責老師", to=‘UserInfo‘, help_text="誰簽的單就選誰") class Student(models.Model): """ 學生表(已報名) """ customer = models.OneToOneField(verbose_name=‘客戶信息‘, to=‘Customer‘) username = models.CharField(verbose_name=‘用戶名‘, max_length=32) password = models.CharField(verbose_name=‘密碼‘, max_length=64) emergency_contract = models.CharField(max_length=32, blank=True, null=True, verbose_name=‘緊急聯系人‘) class_list = models.ManyToManyField(verbose_name="已報班級", to=‘ClassList‘, blank=True) company = models.CharField(verbose_name=‘公司‘, max_length=128, blank=True, null=True) location = models.CharField(max_length=64, verbose_name=‘所在區域‘, blank=True, null=True) position = models.CharField(verbose_name=‘崗位‘, max_length=64, blank=True, null=True) salary = models.IntegerField(verbose_name=‘薪資‘, blank=True, null=True) welfare = models.CharField(verbose_name=‘福利‘, max_length=256, blank=True, null=True) date = models.DateField(verbose_name=‘入職時間‘, help_text=‘格式yyyy-mm-dd‘, blank=True, null=True) memo = models.CharField(verbose_name=‘備註‘, max_length=256, blank=True, null=True) def __str__(self): return self.username class CourseRecord(models.Model): """ 上課記錄表 """ class_obj = models.ForeignKey(verbose_name="班級", to="ClassList") day_num = models.IntegerField(verbose_name="節次", help_text=u"此處填寫第幾節課或第幾天課程...,必須為數字") teacher = models.ForeignKey(verbose_name="講師", to=‘UserInfo‘, limit_choices_to={"depart_id__in": [1002, 1003]}) date = models.DateField(verbose_name="上課日期", auto_now_add=True) course_title = models.CharField(verbose_name=‘本節課程標題‘, max_length=64, blank=True, null=True) course_memo = models.TextField(verbose_name=‘本節課程內容概要‘, blank=True, null=True) has_homework = models.BooleanField(default=True, verbose_name="本節有作業") homework_title = models.CharField(verbose_name=‘本節作業標題‘, max_length=64, blank=True, null=True) homework_memo = models.TextField(verbose_name=‘作業描述‘, max_length=500, blank=True, null=True) exam = models.TextField(verbose_name=‘踩分點‘, max_length=300, blank=True, null=True) def __str__(self): return "{0} day{1}".format(self.class_obj, self.day_num) class StudyRecord(models.Model): course_record = models.ForeignKey(verbose_name="第幾天課程", to="CourseRecord") student = models.ForeignKey(verbose_name="學員", to=‘Student‘) record_choices = ((‘checked‘, "已簽到"), (‘vacate‘, "請假"), (‘late‘, "遲到"), (‘noshow‘, "缺勤"), (‘leave_early‘, "早退"), ) record = models.CharField("上課紀錄", 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("本節成績", choices=score_choices, default=-1) homework_note = models.CharField(verbose_name=‘作業評語‘, max_length=255, blank=True, null=True) note = models.CharField(verbose_name="備註", max_length=255, blank=True, null=True) homework = models.FileField(verbose_name=‘作業文件‘, blank=True, null=True, default=None) stu_memo = models.TextField(verbose_name=‘學員備註‘, blank=True, null=True) date = models.DateTimeField(verbose_name=‘提交作業日期‘, auto_now_add=True) def __str__(self): return "{0}-{1}".format(self.course_record, self.student) class CustomerDistrbute(models.Model): customer = models.ForeignKey("Customer", related_name="customers") consultant = models.ForeignKey(verbose_name="課程顧問", to="UserInfo", limit_choices_to={"depart_id": 1001}) date = models.DateField() status = ( (1, "跟進狀態"), (2, "已報名"), (3, "三天未跟進"), (4, "15天未成單"), ) status = models.IntegerField(choices=status, default=1) memo = models.CharField(max_length=255)
在這些表中有幾個地方需要註意,UserInfo表外鍵關聯了部門表,但是不是關聯的部門表的主鍵,而是code字段
班級和老師還有班主任有多對多和一對多的關聯,其中有一個參數limit_choices_to={"depart_id__in": [1002, 1003]},有這個參數,當使用Form自動生成頁面標簽時,select標簽中只會顯示depart_id在1002和1003中的員工,這個參數的意義在於,老師和班主任都是從UserInfo員工表中篩選的,但是員工表中還有其他人,所以我們不需要讓不相關的人顯示在select標簽中
添加stark組件
創建項目後我們直接將我們stark組件的app復制到項目中即可
同時不要忘記在setting中配置
INSTALLED_APPS = [ ‘django.contrib.admin‘, ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, ‘app01.apps.App01Config‘, ‘stark.apps.StarkConfig‘ ]
簡單使用stark組件
在app01中創建stark.py文件
from stark.service.sites import site, ModelStark from .models import * from django.utils.safestring import mark_safe from django.conf.urls import url from django.shortcuts import HttpResponse, render, redirect site.register(Department) class UserConfig(ModelStark): # 定義的方法 list_display = ["name", "email", "depart"] # 定義的字符串字段 list_display_links = ["name"] 把這個設置成name就是可以通過name編輯 site.register(UserInfo, UserConfig) #必須把這個方法配置在這個裏
site.register(Course) site.register(School) class ClassListConfig(ModelStark): def display_class(self, obj=None, is_header=False): # 這行是必須傳的參數。 必須傳 if is_header: return "班級" 這是前端展示的字段信息 return "%s(%s)" % (obj.course, obj.semester) list_display = [display_class, "teachers", "tutor"] 這是方法和兩個字符串字段 必須是choice字段才可以這麽定義 字符串字段可以直接顯示 site.register(ClassList, ClassListConfig) 方法加在這個類裏的函數
下邊都是一樣的 就是改變了一下字段 和方法
class CustomerConfig(ModelStark): def display_gender(self, obj=None, is_header=False): if is_header: return "性別" return obj.get_gender_display() def display_status(self, obj=None, is_header=False): if is_header: return "狀態" return obj.get_status_display() def display_consultrecord(self, obj=None, is_header=False): if is_header: return "跟進" return mark_safe("<a href=‘/stark/app01/consultrecord/?customer=%s‘>跟進記錄</a>" % (obj.pk)) def display_courses(self, obj=None, is_header=False): if is_header: return "咨詢課程" temp = [] for course in obj.course.all(): tag = "<a href=‘/stark/app01/customer/cancel/%s/%s‘ style=‘padding:6px 3px;border: 1px solid #336699‘>%s</a>" % (obj.pk, course.pk, course.name) # 這是刪除咨詢課程的url,配置好 找到這兩個字段的PK值進行刪除 temp.append(tag) s = "".join(temp) return mark_safe(s) def cancel_course(self, request, customer_id, course_id): customer = Customer.objects.get(pk=customer_id) customer.course.remove(course_id) return redirect(self.get_list_url()) def extra_url(self): temp = [] temp.append(url("^cancel/(\d+)/(\d+)/$", self.cancel_course)) return temp list_display = ["name", display_gender, "consultant", display_courses, display_status, display_consultrecord] list_display_links = ["name"] site.register(Customer, CustomerConfig) class ConsultRecordConfig(ModelStark): list_display = ["customer", "consultant", "date", "note"] site.register(ConsultRecord, ConsultRecordConfig) site.register(CourseRecord) class StudentConfig(ModelStark): list_display = ["username", "class_list"] site.register(Student, StudentConfig) class StudyRecordConfig(ModelStark): def display_record(self, obj=None, is_header=False): if is_header: return "記錄" return obj.get_record_display() def display_score(self, obj=None, is_header=False): if is_header: return "成績" return obj.get_score_display() list_display = ["student", "course_record", display_record, display_score] site.register(StudyRecord, StudyRecordConfig) site.register(CustomerDistrbute)
添加新的url 主要是針對新的界面需要添加的url,
在項目使用中如果我們需要添加新的url該怎麽辦呢,我們可以修改stark組件中的一些內容
def extra_url(self): return [] # 設計二級分發url def get_url_func(self): temp = [] model_name = self.model._meta.model_name app_label = self.model._meta.app_label app_model = (app_label, model_name) temp.append(url("^$", self.change_list, name="%s_%s_list" % app_model)) temp.append(url("^add/$", self.add_view, name="%s_%s_add" % app_model)) temp.append(url("^(\d+)/delete/$", self.del_view, name="%s_%s_delete" % app_model)) temp.append(url("^(\d+)/change/$", self.change_view, name="%s_%s_change" % app_model)) temp.extend(self.extra_url()) return temp
可以看到我們添加了一個新的功能extra_url,默認返回一個空列表,而get_url_func中我們得到的temp會添加extra_url的返回值,這樣,當用戶要添加新的url時,可以重新寫extra_url方法,在其中添加新的url,並寫一個對應的視圖函數,由於self只是當前表的ModelStark對象,所以只會多一條url
class CustomerConfig(ModelStark): def cancel_course(self, request, customer_id, course_id): customer = Customer.objects.get(pk=customer_id) customer.course.remove(course_id) return redirect(self.get_list_url()) def extra_url(self): temp = [] temp.append(url("^cancel/(\d+)/(\d+)/$", self.cancel_course)) return temp list_display = ["name"] list_display_links = ["name"] site.register(Customer, CustomerConfig)
crm 使用stark組件