美文网首页
【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