zoukankan      html  css  js  c++  java
  • CRM系统(第三部分)

     

     1、销售与客户的表结构

    1、公共客户与我的客户

    ---公共客户(公共资源)
    1、没有报名
    2、3天没有跟进
    3、15天没有成单

    客户分布表
    龙泰 男 yuan 2018-5-1 3天未跟进
    龙泰 男 三江 2018-5-5 15天未成单
    龙泰 男 暴雨 2018-5-21 正在跟进

    ---我的客户(抢单)
    crontab:
    2018-5-15 12:00 龙泰 男 三江 2018-5-15 正在跟进

    2018-5-16 0:0
    2018-5-17 0:0
    2018-5-18 0:0
    2018-5-19 0:0 龙泰 男 三江 2018-5-19 3天未跟进


    key: CustomerDistrbute为什么创建 ,为什么不能直接用Customer

    2、思考

    因为:销售可以查看,自己的客户是否已过期,是否正在跟进,月底可以算业绩!
    不能说没谈成,就没有业绩!!

    我的客户与公共用户不能冲突!

    我的客户要一直存在,月末要进行绩效统计,他的状态可以是,正在跟进,3天未跟进

    一过期,就改了。linux定时脚本来完成!!
    linux 固定时间,执行脚本 os 去做,
    每天00:00去监测!

    隔半天或隔一天,脚本每天凌晨监测一遍过期就放到公共客户。

    刷新状态,或者把过期的用户移动到公共客户池子

    可以通过,定时脚本,每天0:0进行

    3、添加新的表

    class CustomerDistrbute(models.Model):
        customer = models.ForeignKey("Customer", related_name="customers",on_delete=True)
        consultant = models.ForeignKey(verbose_name="课程顾问", to="UserInfo", limit_choices_to={"depart_id": 1001},on_delete=True)
        date = models.DateField()
        status = (
            (1, "正在跟进"),
            (2, "已报名"),
            (3, "三天未跟进"),
            (4, "15天未成单"),
        )
        status = models.IntegerField(choices=status, default=1)
    
        memo = models.CharField(max_length=255)
    
        def __str__(self):
            return self.customer.name+":"+self.consultant.name

     

    4、新的表结构

     2、公共客户池

    class CusotmerConfig(ModelStark):
    
        def public_customer(self,request):
            """公共客户"""

        '''
          既然是公共资源,那么怎么才算公共资源呢:
          1.未报名。
          2.三天未跟进。
          3.15天未能成功。
        '''

            import datetime
            now =datetime.datetime.now()
            print(now)
            '''
            datetime.datetime
            datetime.time
            datetime.date
            datetime.timedelta(days=7)
            '''
    
            # 3天未跟进 now - last_consult_date > 3   ----> last_consult_date < now-3
            # 15天未成单 now - recv_date > 3   ----> recv_date < now-15
            delta_day3 = datetime.timedelta(days=3)
            delta_day15 = datetime.timedelta(days=15)
    
            from django.db.models import Q
    
            # Customer.objects.filter(status=2,last_consult_date__lt=now-3)
            # customer_list = Customer.objects.filter(Q(last_consult_date__lt=now-delta_day3)|Q(recv_date__lt=now-delta_day15),status=2)
    
            # 过滤掉 我的客户
            user_id = 2
            customer_list = Customer.objects.filter(Q(last_consult_date__lt=now-delta_day3)|Q(recv_date__lt=now-delta_day15),status=2).exclude(consultant=user_id)
            print(customer_list.query)
            """
                SELECT "crm_customer"."id", "crm_customer"."qq", 
                    "crm_customer"."name", "crm_customer"."gender", 
                    "crm_customer"."education", "crm_customer"."graduation_school", 
                    "crm_customer"."major", "crm_customer"."experience", 
                    "crm_customer"."work_status", "crm_customer"."company", 
                    "crm_customer"."salary", "crm_customer"."source",
                     "crm_customer"."referral_from_id", "crm_customer"."status",
                      "crm_customer"."consultant_id", "crm_customer"."date",
                       "crm_customer"."recv_date", "crm_customer"."last_consult_date" 
                FROM "crm_customer" 
                WHERE (("crm_customer"."last_consult_date" < 2018-06-24 
                  OR "crm_customer"."recv_date" < 2018-06-12) 
                  AND "crm_customer"."status" = 2)
    
            """
            
            print('public_customer_list',customer_list)
         #将这些公共的资源展示到公共资源页面,让销售可以看到具体的情况和选择是否抢单继续跟进。
            return render(request,'public.html',locals())
    
        
    
        def extra_url(self):
            temp = []
            temp.append(url(r"cancel_course/(d+)/(d+)", self.cancel_course))
            temp.append(url(r"public/", self.public_customer))
            return temp
    
    site.register(Customer, CusotmerConfig)

    1、添加public的url

        def extra_url(self):
            temp = []
            temp.append(url(r"cancel_course/(d+)/(d+)", self.cancel_course))
            temp.append(url(r"public/", self.public_customer))
            return temp

     2、 datetime.timedelta ( 时间 + - )

            import datetime
            now =datetime.datetime.now()
            print(now)
            '''
            datetime.datetime
            datetime.time
            datetime.date
            datetime.timedelta(days=7)
            '''
    
            # 3天未跟进 now - last_consult_date > 3   ----> last_consult_date < now-3
            # 15天未成单 now - recv_date > 3   ----> recv_date < now-15
            delta_day3 = datetime.timedelta(days=3)
            delta_day15 = datetime.timedelta(days=15)

     

    3、未报名 且3天未跟进或者15天未成单 

     Q查询 last_consult_date__lt recv_date__lt
            from django.db.models import Q
    # Customer.objects.filter(status=2,last_consult_date__lt=now-3) customer_list = Customer.objects.filter(Q(last_consult_date__lt=now-delta_day3)|Q(recv_date__lt=now-delta_day15),status=2)

     

    4. exclude(排除)

     # 不应该让之前的课程顾问 再看到这个已经放到公共名单的人了
            # 过滤掉 我的客户
            user_id = 2
            customer_list = Customer.objects.filter(Q(last_consult_date__lt=now-delta_day3)|Q(recv_date__lt=now-delta_day15),status=2).exclude(consultant=user_id)

    5. customer_list.query( sql 语句 )

            # print(customer_list.query)
            """
            SELECT "crm_customer"."id", "crm_customer"."qq", 
                "crm_customer"."name", "crm_customer"."gender", 
                "crm_customer"."education", "crm_customer"."graduation_school", 
                "crm_customer"."major", "crm_customer"."experience", 
                "crm_customer"."work_status", "crm_customer"."company", 
                "crm_customer"."salary", "crm_customer"."source",
                 "crm_customer"."referral_from_id", "crm_customer"."status",
                  "crm_customer"."consultant_id", "crm_customer"."date",
                   "crm_customer"."recv_date", "crm_customer"."last_consult_date" 
            FROM "crm_customer" 
            WHERE (("crm_customer"."last_consult_date" < 2018-06-24 
              OR "crm_customer"."recv_date" < 2018-06-12) 
              AND "crm_customer"."status" = 2)
    
            """

     6、跳转标签

                                <td><a href="/stark/crm/consultrecord/?customer={{ customer.pk }}">跟进记录</a></td>
                                <td><a href="/stark/crm/customer/further/{{ customer.pk }}"></a></td>

    7、public.html

     <tbody>
            {% for customer in customer_list %}
                <tr>
                    <td>{{ forloop.counter }}</td>
                    <td>{{ customer.name }}</td>
                    <td>{{ customer.consultant }}</td>
                    <td>{{ customer.qq }}</td>
                    <td><a href="/stark/crm/consultrecord/?customer={{ customer.pk }}">跟进记录</a></td>
                    <td><a href="/stark/crm/customer/futher/{{ customer.pk }}">确认跟进</a></td>
                </tr>
            {% endfor %}
            </tbody>

    3、确认跟进

      

     

    url层

        def extra_url(self):
            temp = []
            temp.append(url(r"cancel_course/(d+)/(d+)", self.cancel_course))
            temp.append(url(r"public/", self.public_customer))
            temp.append(url(r"further/(d+)", self.further))
            return temp

    view层

        def futher(self,request,customer_id):
            user_id=3  #这个是当前登录销售的id。
            delta_day3 = datetime.timedelta(days=3)
            delta_day15 = datetime.timedelta(days=15)
            now=datetime.datetime.now()
            #为该客户更改课程顾问和对应的时间。
            #首先听该在顾客表内将该客户筛选到,然后筛选的是符合公共资源的三条规则,最后将这条记录更新为接单销售的
            #销售人ID,并且把接单时间最后接单时间改为当前。
            ret=Customer.objects.filter(pk=customer_id).filter(Q(last_consult_date__lt=now - delta_day3) | Q(recv_date__lt=now - delta_day15), status=2).update(consultant=user_id,last_consult_date=now,recv_date=now)
            
            #做这个判定是因为,如果2人同时在公共资源页面点击一个顾客,那么第二个客户进去上面的公共资源三规则就不符合了,
            #只有第一个点的才符合,这样第二个也就给他显示一个已经被别人抢单了!
            if  not ret:    #ret是更新操作后返回的更新条数。
                return HttpResponse("已经被跟进!")
                #在新建的表中创建一条记录表示别的销售接单,开始跟进。
    
            #如果跟进了,就在这个CustomerDistrbute表创建一条记录。
            CustomerDistrbute.objects.create(customer_id=customer_id,consultant_id=user_id,status=1,date=now)
            return HttpResponse("跟进成功!")
    
            '''
            这里要注意这个CustomerDistrbute表:
                这个表针对一个顾客,可以有不同的状态,比如小东北最先是销售1接待,但是未能成功,这个表内记录销售1三天未跟进,然后变成公共资源,销售2去跟进,那么销售2的状态显示小东北就是正在跟进。这样同一个客户可以有了动态。
            '''
    
    
    

     1、新增url

        def extra_url(self):
            temp = []
            temp.append(url(r"cancel_course/(d+)/(d+)", self.cancel_course))
            temp.append(url(r"public/", self.public_customer))
            temp.append(url(r"further/(d+)", self.further))
            return temp

    2、改客户的课程顾问,和相应的时间

    未报名 且3天未跟进或者15天未成单

     一定要先过滤;防止多个用户同时抢单,给了 最后一个抢单的人;先过滤之后再抢单,注意提示已经被跟进了。

            # 更改客户的课程顾问,和相应的时间
            # Customer.objects.filter(pk=customer_id).update(consultant=user_id,last_consult_date=now,recv_date=now)
            ret = Customer.objects.filter(pk=customer_id).filter(Q(last_consult_date__lt=now-delta_day3)|Q(recv_date__lt=now-delta_day15),status=2).update(consultant=user_id,last_consult_date = now,recv_date=now)
            if not ret:
                return HttpResponse('已经被跟进了')
    
            return HttpResponse('跟进成功')

    3、客户跟进表的数据

    为我的客户页面做准备

            CustomerDistrbute.objects.create(customer_id=customer_id,consultant_id=user_id,date=now,status=1)

    4、我的客户

     

     1、新增url

            temp.append(url(r"mycustomer/", self.mycustomer))

    2. 客户分布表查询

      不能再 Customer表查询,这里查到的只是正在跟踪的客户信息

      但是,之前跟踪过的客户,状态也要显示

        def mycustomer(self,request):
            user_id=3    #模拟当前登录销售的ID
    
            #取出这个销售所有的客户名单,展示在一个单独页面。
            customer_distrbute_list=CustomerDistrbute.objects.filter(consultant_id=user_id)
            return render(request,"mycustomer.html",locals())

    3、mycustomer.html

    <table class="table-bordered table table-striped">
        <thead>
            <tr>
                <th>客户名字</th>
                <th>跟进人</th>
                <th>跟进状态</th>
                <th>日期</th>
            </tr>
        </thead>
        <tbody>
            {% for customer_distrbute in customer_distrbute_list %}
            <tr>
                <td>{{ customer_distrbute.customer }}</td>
                <td>{{ customer_distrbute.consultant }}</td>
                <td>{{ customer_distrbute.get_status_display }}</td>
                <td>{{ customer_distrbute.date }}</td>
            </tr>
            {% endfor %}
         </tbody>
    </table>    

    4、crontab定时脚本

     

    5、code

    crm/stark.py

    from stark.service.stark import site, ModelStark
    from django.http import JsonResponse
    from .models import *
    
    from django.utils.safestring import mark_safe
    from django.conf.urls import url
    
    from django.shortcuts import HttpResponse, redirect, render
    
    
    site.register(School)
    
    
    class UserConfig(ModelStark):
        list_display = ["name", "email", "depart"]
    
    
    site.register(UserInfo, UserConfig)
    
    
    class ClassConfig(ModelStark):
        def display_classname(self, obj=None, header=False):
            if header:
                return "班级名称"
            class_name = "%s(%s)" % (obj.course.name, str(obj.semester))
            return class_name
    
        list_display = [display_classname, "tutor", "teachers"]
    
    
    site.register(ClassList, ClassConfig)
    
    
    class CusotmerConfig(ModelStark):
        def display_gender(self, obj=None, header=False):
            if header:
                return "性别"
            return obj.get_gender_display()
    
        def display_course(self, obj=None, header=False):
            if header:
                return "咨询课程"
            temp = []
            for course in obj.course.all():
                s = "<a href='/stark/crm/customer/cancel_course/%s/%s' style='border:1px solid #369;padding:3px 6px'><span>%s</span></a>&nbsp;" % (
                    obj.pk, course.pk, course.name,)
                temp.append(s)
            return mark_safe("".join(temp))
    
        # list_display = ["name",'gender','course',"consultant",]
        list_display = ["name", display_gender, display_course, "consultant", ]
    
        def cancel_course(self, request, customer_id, course_id):
            print(customer_id, course_id)
    
            obj = Customer.objects.filter(pk=customer_id).first()
            obj.course.remove(course_id)
            return redirect(self.get_list_url())
    
    
        def public_customer(self,request):
            """公共客户"""
            # 未报名 且3天未跟进或者15天未成单
    
    
            import datetime
            now =datetime.datetime.now()
            print(now)
            '''
            datetime.datetime
            datetime.time
            datetime.date
            datetime.timedelta(days=7)
            '''
    
            # 3天未跟进 now - last_consult_date > 3   ----> last_consult_date < now-3
            # 15天未成单 now - recv_date > 3   ----> recv_date < now-15
            delta_day3 = datetime.timedelta(days=3)
            delta_day15 = datetime.timedelta(days=15)
    
            from django.db.models import Q
    
            # Customer.objects.filter(status=2,last_consult_date__lt=now-3)
            # customer_list = Customer.objects.filter(Q(last_consult_date__lt=now-delta_day3)|Q(recv_date__lt=now-delta_day15),status=2)
    
            # 过滤掉 我的客户
            user_id = 2
            customer_list = Customer.objects.filter(Q(last_consult_date__lt=now-delta_day3)|Q(recv_date__lt=now-delta_day15),status=2).exclude(consultant=user_id)
            print(customer_list.query)
            print('public_customer_list',customer_list)
    
            return render(request,'public.html',locals())
    
        def further(self,request,customer_id):
            user_id = 2  # request.session.get("user_id")
    
            import datetime
            now =datetime.datetime.now()
            delta_day3 = datetime.timedelta(days=3)
            delta_day15 = datetime.timedelta(days=15)
            from django.db.models import Q
    
    
            # 更改客户的课程顾问,和相应的时间
            # Customer.objects.filter(pk=customer_id).update(consultant=user_id,last_consult_date=now,recv_date=now)
            ret = Customer.objects.filter(pk=customer_id).filter(Q(last_consult_date__lt=now-delta_day3)|Q(recv_date__lt=now-delta_day15),status=2).update(consultant=user_id,last_consult_date = now,recv_date=now)
            if not ret:
                return HttpResponse('已经被跟进了')
    
            # 客户跟进表的数据
            CustomerDistrbute.objects.create(customer_id=customer_id,consultant_id=user_id,date=now,status=1)
    
            return HttpResponse('跟进成功')
    
    
    
        def mycustomer(self,request):
            user_id = 2
            customer_distrbute_list = CustomerDistrbute.objects.filter(consultant=user_id)
            print('customer_distrbute_list',customer_distrbute_list)
            return render(request,'mycustomer.html',locals())
    
    
    
        def extra_url(self):
            temp = []
            temp.append(url(r"cancel_course/(d+)/(d+)", self.cancel_course))
            temp.append(url(r"public/", self.public_customer))
            temp.append(url(r"further/(d+)", self.further))
            temp.append(url(r"mycustomer/", self.mycustomer))
            return temp
    
    
    site.register(Customer, CusotmerConfig)
    
    
    site.register(Department)
    site.register(Course)
    
    
    class ConsultConfig(ModelStark):
        list_display = ['customer', 'consultant', 'date', 'note']
    
    
    site.register(ConsultRecord, ConsultConfig)
    
    
    
    class CourseRecordConfig(ModelStark):
        def score(self, request, course_record_id):
            """录入成绩view"""
            study_record_list = StudyRecord.objects.filter(course_record=course_record_id)
            print(study_record_list)
            score_choices = StudyRecord.score_choices
            if request.method == "POST":
                print(request.POST)  # <QueryDict:  'score_4': ['100'], 'homeword_note_4': ['33']}>
    
                data = {}  # dic = {1:{'homework_note':'good','score':'90'},2:{'homework_note':'nonono','score':'80'},}
    
                for key, value in request.POST.items():
                    if key == "csrfmiddlewaretoken": continue
                    field, pk = key.rsplit('_', 1)
    
                    if pk in data:
                        data[pk][field] = value
                    else:
                        data[pk] = {field: value}
    
                    print('data', data)
    
                    for pk, val in data.items():
                        StudyRecord.objects.filter(pk=pk).update(**val)
    
                    '''
                    # 方式1
                    if field == 'score':
                        StudyRecord.objects.filter(pk=pk).update(score=value)
                    else:
                        StudyRecord.objects.filter(pk=pk).update(homework_note=value.strip())
                    '''
    
                return redirect(request.path)  # 跳转到当前url
    
            return render(request, 'score.html', locals())
    
        def extra_url(self):
            """录入成绩url"""
            temp = []
            temp.append(url('record_score/(d+)', self.score))
            return temp
    
        def record_score(self, obj=None, header=False):
            """录入成绩a标签"""
            if header:
                return "录入成绩"
            return mark_safe("<a href='record_score/%s'>录入成绩</a>" % (obj.pk))
    
    
        def record(self, obj=None, header=False):
            if header:
                return '学习记录'
            return mark_safe("<a href='/stark/crm/studyrecord/?course_record=%s'>记录</a>" % (obj.pk))
    
        list_display = ['class_obj', 'day_num', 'teacher', record, record_score]
    
        def patch_studyrecord(self, request, queryset):
            print(queryset)  # <QuerySet [<CourseRecord: python基础班(9期) day11>]>
            temp = []
            for course_record in queryset:
                student_list = Student.objects.filter(class_list=course_record.class_obj.pk)
                for student in student_list:
                    obj = StudyRecord(student=student, course_record=course_record)
                    temp.append(obj)
    
            StudyRecord.objects.bulk_create(temp)  # 批量生成数据
    
        patch_studyrecord.short_description = '批量生成学习记录'
        actions = [patch_studyrecord, ]
    
    
    site.register(CourseRecord, CourseRecordConfig)
    
    
    class StudyRecordConfig(ModelStark):
        def display_record(self, obj=None, header=False):
            if header:
                return "记录"
            return obj.get_record_display()
    
        def display_score(self, obj=None, header=False):
            if header:
                return "成绩"
            return obj.get_score_display()
    
        list_display = ['student', 'course_record', display_record, display_score]
    
        def patch_late(self, request, queryset):
            queryset.update(record='late')
    
        patch_late.short_description = '迟到'
        actions = [patch_late]
    
    
    site.register(StudyRecord, StudyRecordConfig)
    
    
    
    class StudentConfig(ModelStark):
        def score_view(self, request, stu_id):
            """查看成绩 view"""
            if request.is_ajax():
                cid = request.GET.get('cid')
                sid = request.GET.get('sid')
    
                print(cid,sid)
                study_record_list = StudyRecord.objects.filter(student=sid,course_record__class_obj=cid)
    
                print('study_record_list',study_record_list)
    
                # 方案1:构造数据 # [['day11', 85], ['day12', 90]]
                data_list = []
                for study_record in study_record_list:
                    day_num = study_record.course_record.day_num
                    data_list.append(['day%s' % day_num, study_record.score])
    
                print('data_list',data_list)
    
                #方案2:构造数据 dic = {day:[day11,day12],score:[85,90]}
                dic = {'day':[],'score':[]}
                for study_record in study_record_list:
                    day_num = study_record.course_record.day_num
                    dic['day'].append('day%s'%day_num)
                    dic['score'].append(study_record.score)
                print(dic)
                print(dic['day'])
                print(dic['score'])
    
                return JsonResponse(dic,safe=False)
    
            else:
                student = Student.objects.filter(pk=stu_id).first()
                class_list = student.class_list.all()
                return render(request, 'score_view.html', locals())
    
        def extra_url(self):
            """查看成绩url"""
            temp = []
            temp.append(url(r"score_view/(d+)", self.score_view))
            return temp
    
        def score_show(self, obj=None, header=False):
            """查看成绩 a标签"""
            if header:
                return "查看成绩"
            return mark_safe('<a href="score_view/%s">查看成绩</a>' % (obj.pk))
    
        list_display = ['customer', 'class_list', score_show]
        list_display_links = ['customer']
    
    
    site.register(Student, StudentConfig)
     

    stark/service/stark

    # by luffycity.com
    from django.conf.urls import url
    
    from django.shortcuts import HttpResponse,render,redirect
    from django.urls import reverse
    from django.db.models import Q
    from django.utils.safestring import mark_safe
    
    from stark.utils.page import  Pagination
    from django.db.models.fields.related import ManyToManyField,ForeignKey
    
    
    class ShowList(object):
        def __init__(self,config,data_list,request):
            self.config=config
            self.data_list=data_list
            self.request=request
            #分页
            data_count=self.data_list.count()
            current_page=int(self.request.GET.get("page",1))
            base_path=self.request.path
    
            self.pagination=Pagination(current_page,data_count,base_path,self.request.GET,per_page_num=10, pager_count=11, )
            self.page_data=self.data_list[self.pagination.start:self.pagination.end]
    
            # actions
            self.actions=self.config.new_actions() # [patch_init,]
    
    
        def get_filter_linktags(self):
            print("list_filter:",self.config.list_filter)
            link_dic={}
            import copy
    
            for filter_field in self.config.list_filter: # ["title","publish","authors",]
                params = copy.deepcopy(self.request.GET)
    
                cid=self.request.GET.get(filter_field,0)
    
                print("filter_field",filter_field) # "publish"
                filter_field_obj=self.config.model._meta.get_field(filter_field)
                print("filter_field_obj",filter_field_obj)
                print(type(filter_field_obj))
                from django.db.models.fields.related import ForeignKey
                from django.db.models.fields.related import ManyToManyField
                print("rel======...",filter_field_obj.rel)
    
                if isinstance(filter_field_obj,ForeignKey) or isinstance(filter_field_obj,ManyToManyField):
                     data_list=filter_field_obj.rel.to.objects.all()# 【publish1,publish2...】
                else:
                     data_list=self.config.model.objects.all().values("pk",filter_field)
                     print("data_list",data_list)
    
    
                temp=[]
                # 处理 全部标签
                if params.get(filter_field):
                    del params[filter_field]
                    temp.append("<a href='?%s'>全部</a>"%params.urlencode())
                else:
                    temp.append("<a  class='active' href='#'>全部</a>")
    
                # 处理 数据标签
                for obj in data_list:
                    if isinstance(filter_field_obj,ForeignKey) or isinstance(filter_field_obj,ManyToManyField):
                        pk=obj.pk
                        text=str(obj)
                        params[filter_field] = pk
                    else: # data_list= [{"pk":1,"title":"go"},....]
                        print("========")
                        pk=obj.get("pk")
                        text=obj.get(filter_field)
                        params[filter_field] =text
    
    
                    _url=params.urlencode()
                    if cid==str(pk) or cid==text:
                         link_tag="<a class='active' href='?%s'>%s</a>"%(_url,text)
                    else:
                        link_tag = "<a href='?%s'>%s</a>" % (_url, text)
                    temp.append(link_tag)
    
                link_dic[filter_field]=temp
    
            return link_dic
    
    
        def get_action_list(self):
            temp=[]
            for action in self.actions:
               temp.append({
                   "name":action.__name__,
                   "desc":action.short_description
               })  #  [{"name":""patch_init,"desc":"批量初始化"}]
    
            return temp
    
        def get_header(self):
            # 构建表头
            header_list = []
            print("header",
                  self.config.new_list_play())  # [checkbox,"pk","name","age",edit ,deletes]     【checkbox ,"__str__", edit ,deletes】
    
            for field in self.config.new_list_play():
    
                if callable(field):
                    # header_list.append(field.__name__)
                    val = field(self.config, header=True)
                    header_list.append(val)
    
                else:
                    if field == "__str__":
                        header_list.append(self.config.model._meta.model_name.upper())
                    else:
                        # header_list.append(field)
                        val = self.config.model._meta.get_field(field).verbose_name
                        header_list.append(val)
            return header_list
    
        def get_body(self):
            # 构建表单数据
            new_data_list = []
            for obj in self.page_data:
                temp = []
                for filed in self.config.new_list_play():  # ["__str__",]      ["pk","name","age",edit]
                    if callable(filed):
                        print("obj-----:",obj)
                        val = filed(self.config, obj)
                    else:
                        try:
                            field_obj=self.config.model._meta.get_field(filed)
                            if isinstance(field_obj,ManyToManyField):
                                ret = getattr(obj,filed).all()
                                t=[]
                                for mobj in ret:
                                    t.append(str(mobj))
                                val=",".join(t)
                            else:
                                print("+++++>>",field_obj.choices)
                                if field_obj.choices:
                                    val = getattr(obj,'get_'+filed+'_display')
                                else:
                                    val = getattr(obj, filed)
                                if filed in self.config.list_display_links:
                                    # "app01/userinfo/(d+)/change"
                                    _url = self.config.get_change_url(obj)
                                    val = mark_safe("<a href='%s'>%s</a>" % (_url, val))
    
                        except Exception as e:
                            val = getattr(obj, filed)
                    temp.append(val)
                new_data_list.append(temp)
            return new_data_list
    
    '''
            [
                [1,"alex",12],
                [1,"alex",12],
                [1,"alex",12],
                [1,"alex",12],
    
                     ]
    
            '''
    
    class ModelStark(object):
    
        list_display=["__str__",]
        list_display_links=[]
        modelform_class=None
        search_fields=[]
        actions = []
        list_filter=[]
    
    
        def patch_delete(self, request, queryset):
    
            queryset.delete()
    
        patch_delete.short_description = "批量删除"
    
    
    
    
    
        def __init__(self,model,site):
            self.model=model
            self.site=site
    
    
        # 删除 编辑,复选框
        def edit(self,obj=None,header=False):
            if header:
                return "操作"
            #return mark_safe("<a href='%s/change'>编辑</a>"%obj.pk)
            _url=self.get_change_url(obj)
    
            return mark_safe("<a href='%s'>编辑</a>"%_url)
    
        def deletes(self,obj=None,header=False):
            if header:
                return "操作"
            # return mark_safe("<a href='%s/change'>编辑</a>"%obj.pk)
    
            _url=self.get_delete_url(obj)
    
            return mark_safe("<a href='%s'>删除</a>" % _url)
    
        def checkbox(self,obj=None,header=False):
            if header:
                return mark_safe('<input id="choice" type="checkbox">')
    
            return mark_safe('<input class="choice_item" type="checkbox" name="selected_pk" value="%s">'%obj.pk)
    
        def get_modelform_class(self):
    
            if not self.modelform_class:
                from django.forms import ModelForm
                from django.forms import widgets as wid
                class ModelFormDemo(ModelForm):
                    class Meta:
                        model = self.model
                        fields = "__all__"
                        labels={
                            ""
                        }
                return ModelFormDemo
            else:
                return self.modelform_class
    
        def get_new_form(self,form):
    
            for bfield in form:
                from django.forms.boundfield import BoundField
                print(bfield.field) # 字段对象
                print("name",bfield.name)  # 字段名(字符串)
                print(type(bfield.field)) # 字段类型
                from django.forms.models import ModelChoiceField
                if isinstance(bfield.field,ModelChoiceField):
                    bfield.is_pop=True
    
                    print("=======>",bfield.field.queryset.model) # 一对多或者多对多字段的关联模型表
    
                    related_model_name=bfield.field.queryset.model._meta.model_name
                    related_app_label=bfield.field.queryset.model._meta.app_label
    
    
                    _url=reverse("%s_%s_add"%(related_app_label,related_model_name))
                    bfield.url=_url+"?pop_res_id=id_%s"%bfield.name
    
            return form
    
    
        def add_view(self, request):
            ModelFormDemo = self.get_modelform_class()
            form = ModelFormDemo()
    
            form=self.get_new_form(form)
    
    
    
    
            if request.method=="POST":
                form = ModelFormDemo(request.POST)
                if form.is_valid():
                    obj=form.save()
    
                    pop_res_id=request.GET.get("pop_res_id")
    
                    if pop_res_id:
                        res ={"pk":obj.pk,"text":str(obj),"pop_res_id":pop_res_id}
                        import json
                        return render(request, "pop.html", {"res":res})
    
    
    
    
                    else:
                        return redirect(self.get_list_url())
    
    
            return render(request, "add_view.html", locals())
    
        def delete_view(self, request, id):
            url = self.get_list_url()
            if request.method=="POST":
                self.model.objects.filter(pk=id).delete()
                return redirect(url)
    
            return render(request, "delete_view.html", locals())
    
        def change_view(self, request, id):
            ModelFormDemo = self.get_modelform_class()
            print("=====id",id)
            edit_obj = self.model.objects.filter(pk=id).first()
    
            if request.method=="POST":
                form = ModelFormDemo(request.POST,instance=edit_obj)
                if form.is_valid():
                    form.save()
                    return redirect(self.get_list_url())
    
                return render(request, "add_view.html", locals())
    
            print("***********",edit_obj)
            form = ModelFormDemo(instance=edit_obj)
            form = self.get_new_form(form)
    
            return render(request, "change_view.html", locals())
    
        def new_list_play(self):
            temp=[]
            temp.append(ModelStark.checkbox)
            temp.extend(self.list_display)
            if not self.list_display_links:
                temp.append(ModelStark.edit)
            temp.append(ModelStark.deletes)
            return temp
    
        def new_actions(self):
            temp=[]
            temp.append(ModelStark.patch_delete)
            temp.extend(self.actions)
    
            return temp
    
    
        def get_change_url(self,obj):
            model_name = self.model._meta.model_name
            app_label = self.model._meta.app_label
            print("obj===========",obj)
            _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,))
    
            return _url
    
        def get_delete_url(self, obj):
            model_name = self.model._meta.model_name
            app_label = self.model._meta.app_label
    
            _url = reverse("%s_%s_delete" % (app_label, model_name), args=(obj.pk,))
    
            return _url
    
        def get_add_url(self):
    
            model_name = self.model._meta.model_name
            app_label = self.model._meta.app_label
    
            _url = reverse("%s_%s_add" % (app_label, model_name))
    
            return _url
    
        def get_list_url(self):
    
            model_name = self.model._meta.model_name
            app_label = self.model._meta.app_label
    
            _url = reverse("%s_%s_list" % (app_label, model_name))
    
            return _url
    
        def get_serach_conditon(self,request):
            key_word = request.GET.get("q","")
            self.key_word=key_word
    
            search_connection = Q()
            if key_word:
                # self.search_fields # ["title","price"]
                search_connection.connector = "or"
                for search_field in self.search_fields:
                    search_connection.children.append((search_field + "__contains", key_word))
            return search_connection
    
    
        def get_filter_condition(self,request):
            filter_condition=Q()
    
            for filter_field,val in request.GET.items():   # courserecord=2
                # if filter_field in self.list_filter:
                if filter_field != 'page':
                    filter_condition.children.append((filter_field,val))
    
            return filter_condition
    
    
        def list_view(self, request):
            if request.method=="POST":  # action
                print("POST:",request.POST)
                action=request.POST.get("action") # patch_init
                selected_pk=request.POST.getlist("selected_pk")
                action_func=getattr(self,action)
                queryset=self.model.objects.filter(pk__in=selected_pk)
                ret=action_func(request,queryset)
    
                #return ret
    
            # 获取serach的Q对象
            search_connection=self.get_serach_conditon(request)
    
            # 获取filter构建Q对象
    
            filter_condition=self.get_filter_condition(request)
    
            # 筛选获取当前表所有数据
            data_list=self.model.objects.all().filter(search_connection).filter(filter_condition)            # 【obj1,obj2,....】
    
            # 按这ShowList展示页面
            showlist=ShowList(self,data_list,request)
    
            # 构建一个查看URL
            add_url=self.get_add_url()
            return render(request, "list_view.html", locals())
    
    
    
        def extra_url(self):
    
            return []
    
        def get_urls_2(self):
    
            temp = []
    
            model_name=self.model._meta.model_name
            app_label=self.model._meta.app_label
    
            temp.append(url(r"^add/", self.add_view,name="%s_%s_add"%(app_label,model_name)))
            temp.append(url(r"^(d+)/delete/", self.delete_view,name="%s_%s_delete"%(app_label,model_name)))
            temp.append(url(r"^(d+)/change/", self.change_view,name="%s_%s_change"%(app_label,model_name)))
            temp.append(url(r"^$", self.list_view,name="%s_%s_list"%(app_label,model_name)))
    
            temp.extend(self.extra_url())
    
            return temp
    
        @property
        def urls_2(self):
            print(self.model)
            return self.get_urls_2(), None, None
    
    class StarkSite(object):
        def __init__(self):
            self._registry={}
    
        def register(self,model,stark_class=None):
            if not stark_class:
                stark_class=ModelStark
    
            self._registry[model] = stark_class(model, self)
    
    
        def get_urls(self):
            temp=[]
            for model,stark_class_obj in self._registry.items():
                model_name=model._meta.model_name
                app_label=model._meta.app_label
                # 分发增删改查
                temp.append(url(r"^%s/%s/"%(app_label,model_name),stark_class_obj.urls_2))
    
                '''
                url(r"^app01/userinfo/",UserConfig(Userinfo).urls_2),
                url(r"^app01/book/",ModelStark(Book).urls_2), 
                
            
                '''
            return temp
    
        @property
        def urls(self):
    
           return self.get_urls(),None,None
    
    site=StarkSite()
    View Code

     

  • 相关阅读:
    HDU 1813 Escape from Tetris
    BZOJ 2276 Temperature
    BZOJ 4499 线性函数
    BZOJ 3131 淘金
    HDU 5738 Eureka
    POJ 2409 Let it Bead
    POJ 1286 Necklace of Beads
    POJ 1696 Space Ant
    Fox And Jumping
    Recover the String
  • 原文地址:https://www.cnblogs.com/geogre123/p/9741876.html
Copyright © 2011-2022 走看看