- Django + MySQL + Redis编写的高校求职招聘管理系统
- 一、系统介绍
- 二、图片展示
- 1.主页
- 2. 登录注册界面
- 3. 浏览工作职位界面
- 4. 填写简历界面
- 5. 个人中心界面
- 6. 查看申请信息界面
- 7. 后台登录界面
- 8. 后台主界面
- 三、数据库表
- 1.我的所有数据库表
- 2. 我自己创建的额外的表
- 四、代码展示
- 1.项目目录
- 2.关键代码展示
- 1. 注册功能代码
- 2.登录功能代码
- 3.搜索功能代码
- 4. 图片验证码功能
- 5. 短信验证码功能
- 6.钉钉app通知面试者面试
- 7. 导出CSV文件功能
- 8.分层URL
- 总结
一、系统介绍
1.软件介绍
系统:Mac OS
语言:Python 3.7
框架:Django
编辑器:Pycharm(Professional)
数据库:MySQL , Redis(存放验证码)
2.本项目共分为四个角色
- 求职者:
注册登录登出功能(含图片验证码和手机验证码),搜索职位功能,查看工作详细信息功能,填写修改提交简历功能,修改个人信息功能,查看面试进程功能。 - 企业招聘官:
注册登录功能,对面试者的面试情况进行打分功能。 - 企业HR:
注册登录功能,对求职者的信息进行查看功能,通知求职者进入面试流程功能,将求职者信息导出为csv文件功能,指定一面和二面面试官功能,一键发送钉钉app通知面试官和求职者进行面试功能。 - 系统管理员:
拥有对此系统的一切管理权力,对任何信息的增删改查。
1.求职者信息表
2.工作职位表
3. 简历表
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//' , views.detail, name='detail'),
# url(r'^job/(?P\d+)/$', views.detail, name='detail'),
# 提交简历
path('add/', views.ResumeCreateView.as_view(), name='resume-add'),
# path('resume//', 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小白~大佬请直接绕走。后续还会继续完善程序,小伙伴有什么好的建议可以一起分享,这里有一份完整的毕业设计报告,有需求的小伙伴可以联系我,需要源码的小伙伴也可以私信我哦!☺️
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)