学习自极客时间吕老师Django课程
MVP(最小可用产品)开发
- 迭代思维
- OOPP(线上+线下)
- 内裤原则
- 优先线下
- MVP的核心任务
- 忽略细枝末节
- 做合适的假设, 简化,用最短时间开发
确定MVP范围
- 产品核心目标?核心用户?核心场景?
- 产品目标都需要用线上完成或者呈现吗?
- 最小MVP产品要做哪些事情,能达到业务目标?
- 哪些功能不是在客户流程的核心路径上?
- 做哪些假设、简化,能最短时间交付产品,并且可以让业务流程跑起来
企业级数据库设计十个原则
第一轮需求
- 候选人信息 面试反馈信息先存放在同一张表
- 页面按分组展示不同信息
创建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)
网友评论