美文网首页
【Django学习笔记4】MVP开发流程

【Django学习笔记4】MVP开发流程

作者: Geekero | 来源:发表于2021-01-06 17:42 被阅读0次

    学习自极客时间吕老师Django课程

    MVP(最小可用产品)开发

    • 迭代思维
    • OOPP(线上+线下)
      • 内裤原则
      • 优先线下
      • MVP的核心任务
    • 忽略细枝末节
    • 做合适的假设, 简化,用最短时间开发

    确定MVP范围

    1. 产品核心目标?核心用户?核心场景?
    2. 产品目标都需要用线上完成或者呈现吗?
    3. 最小MVP产品要做哪些事情,能达到业务目标?
    4. 哪些功能不是在客户流程的核心路径上?
    5. 做哪些假设、简化,能最短时间交付产品,并且可以让业务流程跑起来

    企业级数据库设计十个原则

    第一轮需求

    1. 候选人信息 面试反馈信息先存放在同一张表
    2. 页面按分组展示不同信息

    创建interview 应用

    (Django) 11:06 luohb@Studynode:~/Django/recruitment 
    $cd interview/
    (Django) 11:06 luohb@Studynode:~/Django/recruitment/interview 
    $ls
    admin.py  apps.py  __init__.py  migrations  models.py  tests.py  views.py
    (Django) 11:06 luohb@Studynode:~/Django/recruitment/interview 
    

    建立模型

    $vi models.py 
    
    from django.db import models
    
    # Create your models here.
    # 第一轮面试结果
    FIRST_INTERVIEW_RESULT_TYPE = ((u'建议复试',u'建议复试'), (u'待定',u'待定'), (u'放弃', u'放弃'))
    
    # 复试面试建议
    INTERVIEW_RESULT_TYPE = ((u'建议录用',u'建议录用'),  (u'待定',u'待定'), (u'放弃', u'放弃'))
    
    # 候选人学历
    DEGREE_TYPE = ((u'本科',u'本科'), (u'硕士',u'硕士'), (u'博士', u'博士'))
    
    # HR终面结论
    HR_SCORE_TYPE = (('S','S'), ('A','A'), ('B','B'), ('C','C'))
    
    
    class Candidate(models.Model):
        # 基础信息
        userid = models.IntegerField(unique=True, blank=True, null=True, verbose_name=u'应聘者ID')
        username = models.CharField(max_length=135, verbose_name='姓名')
        city = models.CharField(max_length=135, verbose_name='城市')
        phone = models.CharField(max_length=135, verbose_name='手机号码')
        email = models.EmailField(max_length=135, blank=True, verbose_name=u'邮箱')
        apply_position = models.CharField(max_length=135, blank=True, verbose_name=u'应聘职位')
        born_address = models.CharField(max_length=135, blank=True, verbose_name=u'生源地')
        gender = models.CharField(max_length=135, blank=True, verbose_name=u'性别')
        candidate_remark = models.CharField(max_length=135, blank=True, verbose_name=u'候选人备注')
        
        # 学校与学历信息
        bachelor_school = models.CharField(max_length=135, blank=True, verbose_name=u'本科学校')
        master_school = models.CharField(max_length=135, blank=True, verbose_name=u'研究生学校')
        master = models.CharField(max_length=135, blank=True, verbose_name=u'博士生学校')
        major = models.CharField(max_length=135, blank=True, verbose_name=u'专业')
        degree = models.CharField(max_length=135, choices=DEGREE_TYPE, blank=True, verbose_name=u'学历')
        
        # 综合能力测评成绩, 笔试测评成绩
        test_score_of_general_ability = models.DecimalField(decimal_places=1, null=True, max_digits=3, blank=True,
                                                            verbose_name=u'综合能力测评成绩')
        paper_score = models.DecimalField(decimal_places=1, null=True, max_digits=3, blank=True, verbose_name=u'笔试成绩')
        
        # 第一轮面试记录
        first_score = models.DecimalField(decimal_places=1, null=True, max_digits=2, blank=True, verbose_name=u'初试分')
        first_learning_ability = models.DecimalField(decimal_places=1, null=True, max_digits=2, blank=True, 
                                                     verbose_name=u'学习能力得分')
        first_professional_competency = models.DecimalField(decimal_places=1, null=True, max_digits=2, blank=True,
                                                            verbose_name=u'专业能力得分')
        first_advantage = models.TextField(max_length=1024, blank=True, verbose_name=u'优势')
        first_disadvantage = models.TextField(max_length=1024, blank=True, verbose_name=u'顾虑和不足')
        first_result = models.CharField(max_length=256, choices=FIRST_INTERVIEW_RESULT_TYPE, blank=True,
                                        verbose_name=u'初试结果')
        first_recommend_position = models.CharField(max_length=256, blank=True, verbose_name='推荐部门')
        first_interviewer = models.CharField(max_length=135, blank=True, verbose_name=u'面试官')
        first_remark = models.CharField(max_length=135, blank=True, verbose_name=u'初试备注')
        
        # 第二轮面试记录
        second_score = models.DecimalField(decimal_places=1, null=True, max_digits=2, blank=True, 
                                           verbose_name=u'专业复试得分')
        second_learning_ability = models.DecimalField(decimal_places=1, null=True, max_digits=2, blank=True,
                                                      verbose_name=u'学习能力得分')
        second_professional_competency = models.DecimalField(decimal_places=1, null=True, max_digits=2, blank=True,
                                                             verbose_name=u'专业能力得分')
        second_pursue_of_excellence = models.DecimalField(decimal_places=1, null=True, max_digits=2, blank=True,
                                                          verbose_name=u'追求卓越得分')
        second_pressure_score = models.DecimalField(decimal_places=1, null=True, max_digits=2, blank=True,
                                                    verbose_name=u'抗压能力得分')
        second_advantage = models.TextField(max_length=1024, blank=True, verbose_name=u'优势')
        second_disadvantage = models.TextField(max_length=1024, blank=True, verbose_name=u'顾虑和不足')
        second_result = models.CharField(max_length=256, choices=INTERVIEW_RESULT_TYPE, blank=True,
                                        verbose_name=u'专业复试结果')
        second_recommend_position = models.CharField(max_length=256, blank=True, verbose_name='推荐方向或推荐部门')
        second_interviewer = models.CharField(max_length=135, blank=True, verbose_name=u'面试官')
        second_remark = models.CharField(max_length=135, blank=True, verbose_name=u'专业复试备注')
        
        # HR终面
        hr_score = models.CharField(max_length=10, choices=HR_SCORE_TYPE, blank=True, 
                                   verbose_name=u'HR复试综合等级')
        hr_responsibility = models.CharField(max_length=10, choices=HR_SCORE_TYPE, blank=True, 
                                             verbose_name=u'HR责任心')
        hr_communication_ability = models.CharField(max_length=10, choices=HR_SCORE_TYPE, blank=True,
                                                    verbose_name=u'HR坦诚沟通')
        hr_logic_ability = models.CharField(max_length=10,  choices=HR_SCORE_TYPE, blank=True,
                                                    verbose_name=u'HR逻辑思维')
        hr_stability = models.CharField(max_length=10,  choices=HR_SCORE_TYPE, blank=True,
                                                    verbose_name=u'HR稳定性')
        hr_advantage = models.TextField(max_length=1024, blank=True, verbose_name=u'优势')
        hr_disadvantage = models.TextField(max_length=1024, blank=True, verbose_name=u'顾虑和不足')
        hr_result = models.TextField(max_length=256, choices=INTERVIEW_RESULT_TYPE, blank=True,
                                        verbose_name=u'HR复试结果')
        hr_interviewer = models.CharField(max_length=256, blank=True, verbose_name=u'HR面试官')
        hr_remark = models.CharField(max_length=135, blank=True, verbose_name=u'HR复试备注')
        
        creator = models.CharField(max_length=256, blank=True, verbose_name=u'候选人数据的创建人')
        created_date = models.DateTimeField(auto_now_add=True, verbose_name=u'创建时间')
        modified_date = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=u'更新时间')
        last_editor = models.CharField(max_length=256, blank=True, verbose_name=u'最后编辑者')
        
        #定义表的meta
        class Meta:
            db_table = u'candidate'
            verbose_name = u'应聘者'
            verbose_name_plural = u'应聘者'
    
        # Python2 优先使用这个方法,把对象转换成字符串,如果没有__unicode__()方法, 使用__str__()方法
        #def __unicode__(self):
        #    return self.username
        
        #Python3 直接定义__str__()方法即可,系统使用这个方法来把对象转换成字符串
        def __str__(self):
            return self.username
    

    将模型注册到Admin

    $cat admin.py 
    from django.contrib import admin
    
    from interview.models import Candidate
    # Register your models here.
    
    admin.site.register(Candidate)
    

    将应用写到整个项目的设置中

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'jobs',
        'interview',
    ]
    

    创建数据库+生效数据库

    Migrations for 'interview':
      interview/migrations/0001_initial.py
        - Create model Candidate
    (Django) 16:37 luohb@Studynode:~/Django/recruitment 
    $python manage.py migrate
    Operations to perform:
      Apply all migrations: admin, auth, contenttypes, interview, jobs, sessions
    Running migrations:
      Applying interview.0001_initial... OK
    

    优化页面

    列表页展现其他字段并分组

    (Django) 16:34 luohb@Studynode:~/Django/recruitment 
    $cat interview/admin.py 
    from django.contrib import admin
    
    from interview.models import Candidate
    # Register your models here.
    
    #定义列表需要展示的字段
    class CandidateAdmin(admin.ModelAdmin):
        exclude = ('creator', 'created_date', 'modified_date')
        
        list_display = (
            "username", "city", "bachelor_school", "first_score", "first_result", "first_interviewer",
            "second_result", "second_interviewer", "hr_score", "hr_result", "last_editor",
        )
        
        #定义字段的集合列表
        fieldsets = (
            (None, {'fields': ("userid", ("username", "city", "phone"), ("email", "apply_position", "born_address"), ("gender", "candidate_remark"), ("bachelor_school", "master_school"), ("master", "major", "degree"), ("test_score_of_general_ability",  "paper_score"), "last_editor")}), #用户的基础信息
            ('第一轮面试记录', {'fields': (("first_score", "first_learning_ability", "first_professional_competency"), "first_advantage", "first_disadvantage", "first_result", "first_recommend_position", "first_interviewer", "first_remark")}),
            ('第二轮专业复试记录', {'fields': (("second_score", "second_learning_ability", "second_professional_competency"), ("second_pursue_of_excellence", "second_pressure_score"), "second_advantage", "second_disadvantage", "second_result", "second_recommend_position", "second_interviewer", "second_remark",)}),
            ('HR复试记录', {'fields': (("hr_score", "hr_responsibility", "hr_communication_ability"), ("hr_logic_ability", "hr_stability"), "hr_advantage", "hr_disadvantage", "hr_result", "hr_interviewer", "hr_remark")}),
        )
        
    admin.site.register(Candidate, CandidateAdmin)
    

    实现Excel导入

    management command 工具 实现命令行操作

    (Django) 16:42 luohb@Studynode:~/Django/recruitment/interview 
    $mkdir -p management/commands
    

    $cat interview/management/commands/import_candidates.py 
    import csv
    
    from django.core.management import BaseCommand
    from interview.models import Candidate
    
    # python manage.py import_candidates --path file.csv
    
    class Command(BaseCommand):
        help = '从一个CSV文件中读取候选人信息,导入数据库中'
        
        def add_arguments(self, parser):
            parser.add_argument('--path', type=str)
       
        def handle(self, *args, **kwargs):
            path = kwargs['path']
            with open(path, 'rt', encoding='gbk') as f:
                reader = csv.reader(f, dialect='excel', delimiter=';')
                for row in reader:
                    candidate = Candidate.objects.create(
                        username = row[0],
                        city = row[1],
                        phone = row[2],
                        bachelor_school = row[3],
                        major = row[4],
                        degree = row[5],
                        test_score_of_general_ability = row[6],
                        paper_score = row[7],
                    )
                    print(candidate)
    

    运行导入命令:

    python manage.py import_candidates --path data/candidates.csv
    

    实现筛选排序功能

    (Django) 17:43 luohb@Studynode:~/Django/recruitment 
    $cat  interview/admin.py 
    from django.contrib import admin
    from datetime import datetime
    from interview.models import Candidate
    # Register your models here.
    
    #定义列表需要展示的字段
    class CandidateAdmin(admin.ModelAdmin):
        exclude = ('creator', 'created_date', 'modified_date')
        
        list_display = (
            "username", "city", "bachelor_school", "first_score", "first_result", "first_interviewer",
            "second_result", "second_interviewer", "hr_score", "hr_result", "last_editor",
        )
        
        ###查询字段
        search_fields = ('username', 'phone', 'email', 'bachelor_school', )
    
        ### 筛选条件
        list_filter = ('city', 'first_result', 'second_result', 'hr_result', 'first_interviewer', 'second_interviewer', 'hr_interviewer',)    
    
        ###默认排序展示
        ordering = ('hr_result', 'second_result', 'first_result',)
    
        #定义字段的集合列表
        fieldsets = (
            (None, {'fields': ("userid", ("username", "city", "phone"), ("email", "apply_position", "born_address"), ("gender", "candidate_remark"), ("bachelor_school", "master_school"), ("master", "major", "degree"), ("test_score_of_general_ability",  "paper_score"), "last_editor")}), #用户的基础信息
            ('第一轮面试记录', {'fields': (("first_score", "first_learning_ability", "first_professional_competency"), "first_advantage", "first_disadvantage", "first_result", "first_recommend_position", "first_interviewer", "first_remark")}),
            ('第二轮专业复试记录', {'fields': (("second_score", "second_learning_ability", "second_professional_competency"), ("second_pursue_of_excellence", "second_pressure_score"), "second_advantage", "second_disadvantage", "second_result", "second_recommend_position", "second_interviewer", "second_remark",)}),
            ('HR复试记录', {'fields': (("hr_score", "hr_responsibility", "hr_communication_ability"), ("hr_logic_ability", "hr_stability"), "hr_advantage", "hr_disadvantage", "hr_result", "hr_interviewer", "hr_remark")}),
        )
        
        def save_models(self, request, obj, form, change):
            obj.last_editor = request.user.username
            if not obj.creator:
                obj.creator = request.user.username
            obj.modified_date = datetime.now()
            obj.save()
    
    admin.site.register(Candidate, CandidateAdmin)
    

    相关文章

      网友评论

          本文标题:【Django学习笔记4】MVP开发流程

          本文链接:https://www.haomeiwen.com/subject/udubnktx.html