栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

【Django快速开发实战】-更新到17章

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Django快速开发实战】-更新到17章

1.总体描述 1.1产品需求:

1.2职位管理系统-建模

1.3 Django项目代码结构

05 | 开始Django之旅 :10分钟如何创建一个可以管理职位的后台 Jobs/models.py的Job模型

created_date 和 modified_date 为自动添加的时间。

from django.db import models
from django.contrib.auth.models import User

# Create your models here.
JobTypes = [
    (0,"技术类"),
    (1,"产品类"),
    (2,"运营类"),
    (3,"设计类"),
    (4,"市场营销类")
]

Cities = [
    (0,"北京"),
    (1,"上海"),
    (2,"深圳"),
    (3,"杭州"),
    (4,"广州")
]


class Job(models.Model):
    # Translators: 职位实体的翻译
    job_type = models.SmallIntegerField(blank=False, choices=JobTypes, verbose_name=("职位类别"))
    job_name = models.CharField(max_length=250, blank=False, verbose_name=("职位名称"))
    job_city = models.SmallIntegerField(choices=Cities, blank=False, verbose_name=("工作地点"))
    job_responsibility = models.TextField(max_length=1024, verbose_name=("职位职责"))
    job_requirement = models.TextField(max_length=1024, blank=False, verbose_name=("职位要求"))
    creator = models.ForeignKey(User, verbose_name=("创建人"), null=True, on_delete=models.SET_NULL)
    created_date = models.DateTimeField(verbose_name=("创建日期"), auto_now_add=True)
    modified_date = models.DateTimeField(verbose_name=("修改日期"), auto_now=True)

    class meta:
        verbose_name = ('职位')
        verbose_name_plural = ('职位列表')

    def __str__(self):
        return self.job_name

06 | 产品体验优化:快速迭代完善应用 admin.py修改

save_model()使creator可以默认选择当前user。

from django.contrib import admin
from jobs.models import Job



class JobAdmin(admin.ModelAdmin):
    exclude = ('creator','created_date','modified_date')
    list_display = ('job_name', 'job_type', 'job_city', 'creator', 'created_date', 'modified_date')

    def save_model(self, request, obj, form, change):
        if obj.creator is None:
            obj.creator = request.user
        super().save_model(request, obj, form, change)



# Register your models here.
admin.site.register(Job,JobAdmin)
http://127.0.0.1:8000/admin/jobs/job/

07 | 添加自定义页面:让匿名用户可以浏览职位列表页 views.py
from django.shortcuts import render

from jobs.models import Job
from jobs.models import Cities, JobTypes

# Create your views here.
def joblist(request):
    job_list = Job.objects.order_by('job_type')
    context =  {'job_list': job_list}
    for job in job_list:
        job.city_name = Cities[job.job_city][1]
        job.type_name = JobTypes[job.job_type][1]
    return render(request, 'joblist.html', context)
template/base.html

匠果科技开放职位

{% block content %} {% endblock %}
template/joblist.html
{% extends 'base.html' %}

{% block content %}

{% if job_list %}
    
    {% for job in job_list %}
  • {{job.type_name}} {{ job.job_name }} {{job.city_name}}
  • {% endfor %}
{% else %}

No jobs are available.

{% endif %} {% endblock %}
recruitment/urls.py
from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path("", include("jobs.urls")),
]

jobs/urls.py
from django.urls import path
from jobs import views


urlpatterns = [
    # 职位列表
    path("joblist/", views.joblist, name="joblist"),
]
http://127.0.0.1:8000/joblist/

08 | 添加自定义页面:让匿名用户可以查看职位详情 template/job.html
{% extends 'base.html' %}

{% block content %}

{% if job %}

岗位名称:{{job.job_name}}

城市: {{job.city_name}}


岗位职责:

{{job.job_responsibility}}
        

任职要求:

{{job.job_requirement}}
        
{% else %}

职位不存在

{% endif %} {% endblock %}
views.py
def detail(request, job_id):
    try:
        job = Job.objects.get(pk=job_id)
        job.city_name = Cities[job.job_city][1]
    except Job.DoesNotExist:
        raise Http404("Job does not exist")
    return render(request, 'job.html', {'job': job})
更新jobs/urls.py
from django.urls import path
from jobs import views


urlpatterns = [
    # 职位列表
    path("joblist/", views.joblist, name="joblist"),

    # 职位详情
    #url(r'^job/(?Pd+)/$', views.detail, name='detail'),
    path('job//', views.detail, name='detail'),
]

09 | 开始一个正式的产品:产品背景、迭代思维与MVP产品规划

10 | 唯快不破:在产品中使用产品迭代思维

11 | 数据建模 & 企业级数据库设计原则

12 | 创建应用和模型,分组展示页面内容

两个需求可以合二为一:1)HR可以维护候选人信息;2)面试官可以维护面试反馈。

interview/models.py
from django.db import models
from django.contrib.auth.models import User

from jobs.models import DEGREE_TYPE

# 第一轮面试结果
FIRST_INTERVIEW_RESULT_TYPE = ((u'建议复试', u'建议复试'), (u'待定', u'待定'), (u'放弃', u'放弃'))

# 复试面试建议
INTERVIEW_RESULT_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=u'姓名')
    city = models.CharField(max_length=135, verbose_name=u'城市')
    phone = models.CharField(max_length=135, verbose_name=u'手机号码')
    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'研究生学校')
    doctor_school = 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'初试分',
                                      help_text=u'1-5分,极优秀: >=4.5,优秀: 4-4.4,良好: 3.5-3.9,一般: 3-3.4,较差: <3分')
    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=u'推荐部门')
    first_interviewer_user = models.ForeignKey(User, related_name='first_interviewer_user', blank=True, null=True, on_delete=models.CASCADE, 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'专业复试得分',
                                       help_text=u'1-5分,极优秀: >=4.5,优秀: 4-4.4,良好: 3.5-3.9,一般: 3-3.4,较差: <3分')
    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_communication_ability = 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=u'建议方向或推荐部门')
    second_interviewer_user = models.ForeignKey(User, related_name='second_interviewer_user', blank=True, null=True, on_delete=models.CASCADE, 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_potential = 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.CharField(max_length=256, choices=INTERVIEW_RESULT_TYPE, blank=True, verbose_name=u'HR复试结果')
    hr_interviewer_user = models.ForeignKey(User, related_name='hr_interviewer_user', blank=True, null=True, on_delete=models.CASCADE, verbose_name=u'HR面试官')
    hr_remark = models.CharField(max_length=256, 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=True, null=True, blank=True, verbose_name=u'更新时间')
    last_editor = models.CharField(max_length=256, blank=True, verbose_name=u'最后编辑者')

    class meta:
        db_table = u'candidate'
        verbose_name = u'应聘者'
        verbose_name_plural = u'应聘者'



    # Python 3 直接定义 __str__() 方法即可,系统使用这个方法来把对象转换成字符串
    def __str__(self):
        return self.username

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_user', 'second_score',
        'second_result', 'second_interviewer_user', 'hr_score', 'hr_result', 'hr_interviewer_user',)

    # 分组展示字段,分三块,基础信息、第一轮面试记录、第二轮面试(专业复试)、HR复试
    fieldsets = (
        (None, {'fields': (
        "userid", ("username", "city", "phone"), ("email", "apply_position", "born_address", "gender", "candidate_remark"),
        ("bachelor_school", "master_school", "doctor_school"), ("major", "degree"), "test_score_of_general_ability",
        "paper_score",)}),
        ('第一轮面试', {'fields': (
        ("first_score", "first_learning_ability", "first_professional_competency"), "first_advantage", "first_disadvantage",
        "first_result", "first_recommend_position", "first_interviewer_user", "first_remark",)}),
        ('第二轮面试(专业复试)', {'fields': ("second_score", ("second_learning_ability", "second_professional_competency"), (
        "second_pursue_of_excellence", "second_communication_ability", "second_pressure_score"), "second_advantage",
                                    "second_disadvantage", "second_result", "second_recommend_position",
                                    "second_interviewer_user", "second_remark",)}),
        ('HR复试', {'fields': (
        "hr_score", ("hr_responsibility", "hr_communication_ability", "hr_logic_ability"), ("hr_potential", "hr_stability"),
        "hr_advantage", "hr_disadvantage", "hr_result", "hr_interviewer_user", "hr_remark",)}),
    )


admin.site.register(Candidate, CandidateAdmin)

http://127.0.0.1:8000/admin/interview/candidate/

http://127.0.0.1:8000/admin/interview/candidate/1/change/

13 | 产品新需求:如何批量从Excel文件导入候选人数据(命令行工具) 参考django官方文档链接 新增interviewmanagementcommandsimport_candidates.py

可以使用python manage.py import_candidates --path /path/to/your/file.csv来批量导入信息。

import csv
from django.core.management import baseCommand
from interview.models import Candidate

# run command to import candidates:
# python manage.py import_candidates --path /path/to/your/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)
命令行
C:UsersSeasonDesktop4.python网页前后端Django基础教程workspace4-recruitingrecruitment【13-】>python manage.py import_candidates --path candidates.csv
刘倩
陈欣欣
刘德华
李小龙
http://127.0.0.1:8000/admin/interview/candidate/

admin管理界面可以看到批量导入的名单。

14 | 产品体验优化:候选人列表筛选和查询 更新interview/admin.py

新增以下代码

    # 右侧筛选条件
    list_filter = ('city','first_result','second_result','hr_result','first_interviewer_user','second_interviewer_user','hr_interviewer_user')

    # 查询字段
    search_fields = ('username', 'phone', 'email', 'bachelor_school')

    ### 列表页排序字段
    ordering = ('hr_result','second_result','first_result',)

变更后的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_user', 'second_score',
        'second_result', 'second_interviewer_user', 'hr_score', 'hr_result', 'hr_interviewer_user',)


    # 右侧筛选条件
    list_filter = ('city','first_result','second_result','hr_result','first_interviewer_user','second_interviewer_user','hr_interviewer_user')

    # 查询字段
    search_fields = ('username', 'phone', 'email', 'bachelor_school')

    ### 列表页排序字段
    ordering = ('hr_result','second_result','first_result',)


    # 分组展示字段,分三块,基础信息、第一轮面试记录、第二轮面试(专业复试)、HR复试
    fieldsets = (
        (None, {'fields': (
        "userid", ("username", "city", "phone"), ("email", "apply_position", "born_address", "gender", "candidate_remark"),
        ("bachelor_school", "master_school", "doctor_school"), ("major", "degree"), "test_score_of_general_ability",
        "paper_score",)}),
        ('第一轮面试', {'fields': (
        ("first_score", "first_learning_ability", "first_professional_competency"), "first_advantage", "first_disadvantage",
        "first_result", "first_recommend_position", "first_interviewer_user", "first_remark",)}),
        ('第二轮面试(专业复试)', {'fields': ("second_score", ("second_learning_ability", "second_professional_competency"), (
        "second_pursue_of_excellence", "second_communication_ability", "second_pressure_score"), "second_advantage",
                                    "second_disadvantage", "second_result", "second_recommend_position",
                                    "second_interviewer_user", "second_remark",)}),
        ('HR复试', {'fields': (
        "hr_score", ("hr_responsibility", "hr_communication_ability", "hr_logic_ability"), ("hr_potential", "hr_stability"),
        "hr_advantage", "hr_disadvantage", "hr_result", "hr_interviewer_user", "hr_remark",)}),
    )


admin.site.register(Candidate, CandidateAdmin)

#admin.site.register(Candidate)

http://127.0.0.1:8000/admin/interview/candidate/?o=11.8.-5

15 | 省去单独的账号管理工作:企业域账号集成(略) 16 | 批量设置面试官:面试官的导入、授权(略) 17 | 产品新需求 :如何导出候选人的数据到CSV(增加自定义的数据操作菜单) interview/admin.py

新增export_model_as_csv()、exportable_fields ,将actions = (export_model_as_csv, )加进去class CandidateAdmin。

from django.contrib import admin
from django.http import HttpResponse
from interview.models import Candidate
from datetime import datetime
import csv
# Register your models here.

exportable_fields = ('username', 'city', 'phone', 'bachelor_school', 'master_school', 'degree', 'first_result', 'first_interviewer_user',
                     'second_result', 'second_interviewer_user', 'hr_result', 'hr_score', 'hr_remark', 'hr_interviewer_user')


# define export action
def export_model_as_csv(modeladmin, request, queryset):
    response = HttpResponse(content_type='text/csv')
    field_list = exportable_fields
    response['Content-Disposition'] = 'attachment; filename=%s-list-%s.csv' % (
        'recruitment-candidates',
        datetime.now().strftime('%Y-%m-%d-%H-%M-%S'),
    )

    # 写入表头
    writer = csv.writer(response)
    writer.writerow(
        [queryset.model._meta.get_field(f).verbose_name.title() for f in field_list],
    )

    for obj in queryset:
        ## 单行 的记录(各个字段的值), 根据字段对象,从当前实例 (obj) 中获取字段值
        csv_line_values = []
        for field in field_list:
            field_object = queryset.model._meta.get_field(field)
            field_value = field_object.value_from_object(obj)
            csv_line_values.append(field_value)
        writer.writerow(csv_line_values)

    return response


export_model_as_csv.short_description = u'导出为CSV文件'





# 候选人管理类
class CandidateAdmin(admin.ModelAdmin):
    exclude = ('creator', 'created_date', 'modified_date')

    actions = (export_model_as_csv,  )


    list_display = (
        'username', 'city', 'bachelor_school', 'first_score', 'first_result', 'first_interviewer_user', 'second_score',
        'second_result', 'second_interviewer_user', 'hr_score', 'hr_result', 'hr_interviewer_user',)


    # 右侧筛选条件
    list_filter = ('city','first_result','second_result','hr_result','first_interviewer_user','second_interviewer_user','hr_interviewer_user')

    # 查询字段
    search_fields = ('username', 'phone', 'email', 'bachelor_school')

    ### 列表页排序字段
    ordering = ('hr_result','second_result','first_result',)


    # 分组展示字段,分三块,基础信息、第一轮面试记录、第二轮面试(专业复试)、HR复试
    fieldsets = (
        (None, {'fields': (
        "userid", ("username", "city", "phone"), ("email", "apply_position", "born_address", "gender", "candidate_remark"),
        ("bachelor_school", "master_school", "doctor_school"), ("major", "degree"), "test_score_of_general_ability",
        "paper_score",)}),
        ('第一轮面试', {'fields': (
        ("first_score", "first_learning_ability", "first_professional_competency"), "first_advantage", "first_disadvantage",
        "first_result", "first_recommend_position", "first_interviewer_user", "first_remark",)}),
        ('第二轮面试(专业复试)', {'fields': ("second_score", ("second_learning_ability", "second_professional_competency"), (
        "second_pursue_of_excellence", "second_communication_ability", "second_pressure_score"), "second_advantage",
                                    "second_disadvantage", "second_result", "second_recommend_position",
                                    "second_interviewer_user", "second_remark",)}),
        ('HR复试', {'fields': (
        "hr_score", ("hr_responsibility", "hr_communication_ability", "hr_logic_ability"), ("hr_potential", "hr_stability"),
        "hr_advantage", "hr_disadvantage", "hr_result", "hr_interviewer_user", "hr_remark",)}),
    )


admin.site.register(Candidate, CandidateAdmin)

#admin.site.register(Candidate)

http://127.0.0.1:8000/admin/interview/candidate/


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/488329.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号