Django + MySQL + Redis编写的高校求职招聘管理系统
文章目录
一、系统介绍
1.软件介绍
系统:Mac OS
语言:Python 3.7
框架:Django
编辑器:Pycharm(Professional)
数据库:MySQL , Redis(存放验证码)
2.本项目共分为四个角色
- 求职者:
注册登录登出功能(含图片验证码和手机验证码),搜索职位功能,查看工作详细信息功能,填写修改提交简历功能,修改个人信息功能,查看面试进程功能。 - 企业招聘官:
注册登录功能,对面试者的面试情况进行打分功能。 - 企业HR:
注册登录功能,对求职者的信息进行查看功能,通知求职者进入面试流程功能,将求职者信息导出为csv文件功能,指定一面和二面面试官功能,一键发送钉钉app通知面试官和求职者进行面试功能。 - 系统管理员:
拥有对此系统的一切管理权力,对任何信息的增删改查。
二、图片展示
1.主页
2. 登录注册界面
3. 浏览工作职位界面
4. 填写简历界面
5. 个人中心界面
6. 查看申请信息界面
7. 后台登录界面
8. 后台主界面
三、数据库表
1.我的所有数据库表
2. 我自己创建的额外的表
1.求职者信息表
2.工作职位表
3. 简历表
四、代码展示
1.项目目录
2.关键代码展示
1. 注册功能代码
class RegisterView(View):
def get(self,request):
return render(request, 'register.html')
def post(self,request):
# Receive parameters
mobile = request.POST.get('mobile')
password = request.POST.get('password')
password2 = request.POST.get('password2')
smscode = request.POST.get('sms_code')
# Check whether the parameters are complete
if not all([mobile, password, password2, smscode]):
return HttpResponseBadRequest('Mandatory parameters are missing')
# Determine if the phone number is legitimate
if not re.match(r'^1[3-9]\d{9}$', mobile):
return HttpResponseBadRequest('Please enter the correct mobile phone number')
# Determine if the password is 8-20 digits long
if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
return HttpResponseBadRequest('Please enter a password of 8-20 characters')
# Check whether the two passwords are the same
if password != password2:
return HttpResponseBadRequest('The entered passwords are inconsistent')
# Verify SMS verification code
redis_conn = get_redis_connection('default')
sms_code_server = redis_conn.get('sms:%s' % mobile)
if sms_code_server is None:
return HttpResponseBadRequest('The SMS verification code has expired')
if smscode != sms_code_server.decode():
return HttpResponseBadRequest('The SMS verification code is incorrect')
# Save registration Data
try:
user = User.objects.create_user(username=mobile, password=password)
except DatabaseError:
return HttpResponseBadRequest('Registration failed')
# Implement state retention
from django.contrib.auth import login
login(request, user)
# respond to registration results
# redirect means to redirect
# reverse is used to get the route of the view through namespace:name
response = redirect(reverse('joblist'))
response.set_cookie('is_login',True)
response.set_cookie('username',user.username,max_age=7*24*3600)
return response
2.登录功能代码
class LoginView(View):
def get(self,request):
return render(request, 'login.html')
def post(self,request):
# 1.Receive parameters
mobile = request.POST.get('username')
password = request.POST.get('password')
remember = request.POST.get('remember')
# 2.Validation of parameters
# 2.1 Verify that the mobile phone number complies with the rules
if not re.match(r'^1[3-9]\d{9}$',mobile):
return HttpResponseBadRequest('The mobile number does not comply with the rules')
# 2.2 Verify that the password complies with rules
if not re.match(r'^[a-zA-Z0-9]{8,20}$',password):
return HttpResponseBadRequest('The password is invalid')
# 3. User authentication login
# Use the system's own authentication method for authentication
# if our username and password are correct, we will return user
# If our username or password is incorrect, None will be returned
from django.contrib.auth import authenticate
user = authenticate(username=mobile,password=password)
if user is None:
return HttpResponseBadRequest('The user name or password is incorrect')
# 4.Maintenance of state
from django.contrib.auth import login
login(request,user)
# 5. Determine whether the user chooses to remember the login state
# 6. We need to set some cookie information for the home page display
# Jump to the page according to the next parameter
next_page = request.GET.get('next')
if next_page:
response = redirect(next_page)
else:
response = redirect(reverse('joblist'))
if remember != 'on': # User information is not remembered
# When the browser is closed
request.session.set_expiry(0)
response.set_cookie('is_login',True)
response.set_cookie('username',user.username,max_age=14*24*3600)
else: # Remember user information
# The default is 2 weeks
request.session.set_expiry(None)
response.set_cookie('is_login',True,max_age=14*24*3600)
response.set_cookie('username',user.username,max_age=14*24*3600)
# 7.Returns a response
return response
3.搜索功能代码
def search(request):
return render(request,"base.html",{})
def handle(request):
text = request.POST["search content"]
db = Job.objects.all()
po_list = []
# job = Job.objects.get(pk=job_id)
for i in db:
i.city_name = Cities[i.job_city][1]
i.type_name = JobTypes[i.job_type][1]
if text in i.job_name:
# po_list.append(i.type_name)
po_list.append(i.job_name)
# po_list.append(i.city_name)
return render(request,"responce.html",{"resp":po_list})
4. 图片验证码功能
class ImageCodeView(View):
def get(self,request):
#Gets the parameters passed from the front end
uuid = request.GET.get('uuid')
#Check whether the parameter is None
if uuid is None:
return HttpResponseBadRequest('请求参数错误')
# Get verification code content and verification code image binary data
text, image = captcha.generate_captcha()
# Save the image to Redis and set the expiration time
redis_conn = get_redis_connection('default')
redis_conn.setex('img:%s' % uuid, 300, text)
# Returns the response, returning the resulting image to the request as content_type image/ JPEG
return HttpResponse(image, content_type='image/jpeg')
5. 短信验证码功能
class SmsCodeView(View):
def get(self,request):
# Receive parameters
image_code_client = request.GET.get('image_code')
uuid = request.GET.get('uuid')
mobile=request.GET.get('mobile')
# Calibration parameters
if not all([image_code_client, uuid,mobile]):
return JsonResponse({'code': RETCODE.NECESSARYPARAMERR, 'errmsg': '缺少必传参数'})
# Create objects connected to Redis
redis_conn = get_redis_connection('default')
# Extract the graphic verification code
image_code_server = redis_conn.get('img:%s' % uuid)
if image_code_server is None:
# Graphic verification code expired or does not exist
return JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '图形验证码失效'})
try:
redis_conn.delete('img:%s' % uuid)
except Exception as e:
logger.error(e)
# Compare the graphic verification code
image_code_server = image_code_server.decode() # Bytes to string
if image_code_client.lower() != image_code_server.lower(): # Lower case and compare
return JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '输入图形验证码有误'})
# Generate SMS verification code: Generates a six-digit verification code
sms_code = '%06d' % randint(0, 999999)
#Output the verification code to the console for easy debugging
logger.info(sms_code)
# Save the SMS verification code to Redis and set the validity period
redis_conn.setex('sms:%s' % mobile, 300, sms_code)
# Send the SMS verification code
CCP().send_template_sms(mobile, [sms_code, 5],1)
# response
return JsonResponse({'code': RETCODE.OK, 'errmsg': 'send successfully'})
6.钉钉app通知面试者面试
def notify_interviewer(modeladmin, request, queryset):
candidates = ""
interviewers = ""
for obj in queryset:
candidates = obj.username + ";" + candidates
# interviewers = obj.first_interviewer_user.username + ";" + interviewers
interviewers = interviewers
# Messages here are sent to the spikes or asynchronously via Celery to the spikes
dingtalk.send("Candidate %s is(are) coming for the interview. Dear interviewer, please prepare for the interview:: %s" % (candidates, interviewers))
messages.add_message(request, messages.INFO, 'The interview notice has been sent successfully')
notify_interviewer.short_description = u'Notify the first interviewer'
7. 导出CSV文件功能
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'),
)
# Written to the header
writer = csv.writer(response)
writer.writerow(
# Use this function to get f, change it to Chinese, iterate over it and print it
[queryset.model._meta.get_field(f).verbose_name.title() for f in field_list],
)
# Queryset is the data for each row we selected
for obj in queryset:
# A single-line record (the value of each field) that gets the field value from the current instance (obj) based on the field object
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)
logger.info(" %s has exported %s candidate records" % (request.user.username, len(queryset)))
return response
export_model_as_csv.allowed_permissions = ('export',)
8.分层URL
1.一层URL
urlpatterns = [
path('admin/', admin.site.urls),
path('', include("jobs.urls")),
# path('accounts/', include('registration.backends.simple.urls')),
]
2.二层URL
urlpatterns = [
# 职位列表
path("joblist/", views.joblist, name="joblist"),
# 职位详情
path('job/<int:job_id>/', views.detail, name='detail'),
# url(r'^job/(?P<job_id>\d+)/$', views.detail, name='detail'),
# 提交简历
path('add/', views.ResumeCreateView.as_view(), name='resume-add'),
# path('resume/<int:pk>/', views.ResumeDetailView.as_view(), name='resume-detail'),
# 首页自动跳转到 职位列表
path("", views.joblist, name="name"),
#简历填写
# path('resume/add/',views.add_resume,name='addResume'),
# 注册
path('register/',RegisterView.as_view(),name='register'),
#图片验证码
path('imagecode/', ImageCodeView.as_view(),name='imagecode'),
# 短信发送
path('smscode/', SmsCodeView.as_view(), name='smscode'),
# 登录路由
path('login/', LoginView.as_view(), name='login'),
# 退出登录路由
path('logout/', LogoutView.as_view(), name='logout'),
# 个人中心
path('center/', UserCenterView.as_view(),name='center'),
# 搜索
path('search/', views.search, name='search'),
# 搜索展示
path('handle/',views.handle,name='handle'),
# 简历填写
path('resume/',views.Resume,name='resume'),
# 申请管理
path('apply/', ApplyView.as_view(),name='apply'),
]
总结
本人是个Django小白~大佬请直接绕走。后续还会继续完善程序,小伙伴有什么好的建议可以一起分享,这里有一份完整的毕业设计报告,有需求的小伙伴可以联系我,需要源码的小伙伴也可以私信我哦!☺️