catalogue
5.2.1 release of Recruitment Information
5.2.2 upload of application information based on model form
5.5.2 development of data download list page
5.1 basic framework
The content of the previous course focuses on the basic design framework of the portal, covering basic knowledge points such as page production, page switching, database operation, background system management, template display and so on. On this basis, this lesson will further enrich the functions of the portal by learning some common third-party tools and interfaces. This chapter corresponds to the contactApp application in the Hengda project and is divided into two sub pages: "welcome to consult" and "join Hengda". The "welcome to consultation" sub page mainly displays the enterprise's address, telephone, contact, location map and other relevant information. This part of the content is a static page, and the content continues the previous template, so readers can try it by themselves. The "join Hengda" sub page mainly constructs a simple online interactive system guided by recruitment and application needs. Recruiters can publish recruitment information through the background management system and display it on the "join Hengda" page. After browsing the recruitment information, users can submit resume information in the form of form for application. After the user submits the information, The background server will send mail notification to the specified mailbox through the mail service. This section focuses on form based information upload, e-mail sending, trigger, etc. It should be noted that these technical points are not necessary for making enterprise portal websites, but mastering these contents in this chapter will help deepen the understanding of the front end and Python Web and further enrich the content of enterprise portal websites.
Before describing the application of each component, you need to develop the basic page corresponding to the two sub pages of the talent recruitment module. from Sample website According to the interface effect shown, the main parts of the two sub pages are still in the form of left and right layout, with the secondary navigation bar on the left and the specific content information on the right. Each sub page is displayed in the form of an independent page. Because the content is relatively simple and highly consistent with lesson 3, this chapter will not repeat the page layout and sub page switching process design. Readers can complete the page design and background coding according to the content of lesson 3 and the final implementation effect. At the same time, they can refer to the code of supporting resources of this course to view the complete details. Here we will only explain the key parts. The "welcome to consult" sub page corresponds to the contact.html file under the templates folder, and the "join us" sub page corresponds to the recruit.html file. In addition, we also design a unique CSS style for the "talent recruitment" application, so we create a contact.css style file under the same directory as style.css.
The renderings of the welcome page are as follows:
5.2 use of signal trigger
reference resources Sample website As a recruitment page, the "join Hengda" page allows recruiters to publish recruitment information on this page through the background management system, and also allows candidates to upload personal application information to the background through forms, so that recruiters can view application information. The candidate will receive the email notification sent by the system after passing the initial interview. Through the development of such a recruitment and recruitment module, a simple online interactive system can be formed.
5.2.1 release of Recruitment Information
In order to enable the website administrator to dynamically publish recruitment information, the corresponding recruitment advertisement model needs to be created in the database, so that the background management system can be used to publish, view and manage recruitment information. Next, create a recruitment advertisement model Ad in contactApp. Open the models.py file in contactApp and add the model:
from django.db import models from django.utils import timezone class Ad(models.Model): title = models.CharField(max_length=50, verbose_name='Recruitment position') description = models.TextField(verbose_name='Job requirements') publishDate = models.DateTimeField(max_length=20, default=timezone.now, verbose_name='Release time') def __str__(self): return self.title class Meta: verbose_name = 'employment ad' verbose_name_plural = 'employment ad' ordering = ('-publishDate', )
The Ad model contains three fields, which respectively represent recruitment position, position requirements and publishing time. After adding the above model, perform data migration, and enter the following commands in the terminal to complete database synchronization:
python manage.py makemigrations python manage.py migrate
Finally, edit the admin.py file and register the model in the background management system admin:
from django.contrib import admin from .models import Ad admin.site.register(Ad)
Then open the background management system and add several recruitment records in the recruitment module, as shown in the following figure:
Next, modify the view processing function. Each time the "join Hengda" page is requested, the background system takes out all recruitment information from the database in the order of time from near to far, passes it into the template file recruit.html, and is rendered by the front end. Re edit the recruit function in the views.py file:
from .models import Ad def recruit(request): AdList = Ad.objects.all().order_by('-publishDate') return render(request, 'recruit.html', { 'active_menu': 'contact', 'sub_menu': 'recruit', 'AdList': AdList })
Finally, the front page is designed and the recruitment information is displayed one by one. We use the "accordion" panel component provided by Bootstrap to display the recruitment list information. The style class of the component is class = "panel group". The component can be regarded as a container of panels, and multiple panels can be placed. Each panel is used to display a piece of information, and each panel can be folded. The core code is given below:
<div class="model-details"> <div class="panel-group" id="accordion"> {% for ad in AdList %} <div class="panel panel-default"> <div class="panel-heading" role="tab" id="panel{{ad.id}}"> <h4 class="panel-title"> {% if forloop.first %} <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse{{ad.id}}"> {% else %} <a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapse{{ad.id}}"> {% endif %} {{ad.title}} </a> </h4> </div> {% if forloop.first %} <div id="collapse{{ad.id}}" class="panel-collapse collapse in"> {% else %} <div id="collapse{{ad.id}}" class="panel-collapse collapse"> {% endif %} <div class="panel-body"> <p>{{ad.description}}</p> </div> </div> </div> {% endfor %} </div> </div> </div>
It is worth noting that the folding effect of panels needs to bind the id of each panel. In order to distinguish the id numbers of each panel, you need to dynamically generate the id of each panel by passing in the recruitment information id number. In addition, the above code uses the condition judgment statement in the template label language:
{% if forloop.first %} ...Execution 1 {% else %} ...Execution 2 {% endif %}
If the current cycle is executed for the first time, execute condition 1; Otherwise, execute condition 2. Through the above logical judgment, the first recruitment information and the rest recruitment information can be displayed separately (the first recruitment information is opened by default and the rest are folded by default). Similarly, in order to beautify the list display effect, you need to set its CSS style. Add the corresponding style code in the contact.css file:
/* Accordion folding panel style */ #accordion a:hover,a:focus{ text-decoration: none; outline: none; } #accordion{ padding-right: 24px; padding-left: 24px; z-index: 1; } #accordion .panel{ border: none; box-shadow: none; } #accordion .panel-heading{ padding: 0; border-radius: 0; border: none; } #accordion .panel-title{ padding: 0; } #accordion .panel-title a{ display: block; font-size: 16px; font-weight: bold; background: #005197; color: #fff; padding: 15px 25px; position: relative; margin-left: -24px; transition: all 0.3s ease 0s; } #accordion .panel-title a.collapsed{ background: #2e516d; color: #fff; margin-left: 0; transition: all 0.3s ease 0s; } #accordion .panel-title a:before{ content: ""; border-left: 24px solid #005197; border-top: 24px solid transparent; border-bottom: 24px solid transparent; position: absolute; top: 0; right: -24px; transition: all 0.3s ease 0s; } #accordion .panel-title a.collapsed:before{ border-left-color: #2e516d; } #accordion .panel-title a:after{ content: "\e133"; font-family: 'Glyphicons Halflings'; position: absolute; top: 30%; right: 15px; font-size: 18px; color: #fff; } #accordion .panel-title a.collapsed:after{ content: "\e134"; color: #fff; } #accordion .panel-collapse{ position: relative; } #accordion .panel-collapse.in:before{ content: ""; border-right: 24px solid rgb(146, 143, 143); border-bottom: 18px solid transparent; position: absolute; top: 0; left: -24px; } #accordion .panel-body{ font-size: 14px; color: #333; background: #e4e4e4; border-top: none; z-index: 1; }
The final effect is shown in the figure below:
5.2.2 upload of application information based on model form
This section focuses on the use of forms in Django. The form itself is also a component of HTML. The form can organize and package the user's input information and send it to the back-end server. The back-end server can extract these information one by one through the request.GET.get function, and then package it into a piece of data and store it in the database after passing the verification. This method of extracting information one by one is not very convenient in actual use. An additional parsing step needs to be added between the user and the background database, and error checking cannot be automatically performed for the fields uploaded by the user (for example, some fields cannot be empty, some fields can only be numbers, etc.). So is there a framework that can directly complete the intermediate form data parsing, validation and storage steps, so that users seem to be directly operating the back-end database? The answer is yes. Django has a built-in form framework that allows you to manage this series of form operations in a simple way. Under this form framework, the corresponding form fields can be defined according to the data model, and the verification method for each field can be specified. It is worth mentioning that Django forms also provide a flexible way to render forms and manipulate data.
Django provides two basic classes of forms:
- Form: standard form. The input data can be verified, but it is not associated with the database model;
- ModelForm: model form. The input data can be verified and associated with the database model, and the database data can be stored and modified directly through the model form;
In order to facilitate development, this section focuses on the use of model forms. There are three steps:
(1) Define the model;
(2) Create a model form according to the model;
(3) The view processing function receives and parses the data through the model form, and finally renders the page;
First, the data model is defined for users. The uploaded data are mainly for personal information, including name, gender, ID number, mailbox, date of birth, education, graduation school, professional, photo, job application, work or learning experience.
Add a Resume model in the models.py file. As a "Resume" model, this model will manage and store all information fields uploaded by users. The specific codes are as follows:
from datetime import datetime class Resume(models.Model): name = models.CharField(max_length=20, verbose_name='full name') personID = models.CharField(max_length=30, verbose_name='ID number') sex = models.CharField(max_length=5, default='male', verbose_name='Gender') email = models.EmailField(max_length=30, verbose_name='mailbox') birth = models.DateField(max_length=20, default=datetime.strftime(datetime.now(), "%Y-%m-%d"), verbose_name='date of birth') edu = models.CharField(max_length=5, default='undergraduate', verbose_name='education') school = models.CharField(max_length=40, verbose_name='University one is graduated from') major = models.CharField(max_length=40, verbose_name='major') position = models.CharField(max_length=40, verbose_name='Apply for position') experience = models.TextField(blank=True, null=True, verbose_name='Study or work experience') photo = models.ImageField(upload_to='contact/recruit/%Y_%m_%d', verbose_name='Personal photos') grade_list = ( (1, 'Not reviewed'), (2, 'adopt'), (3, 'Fail'), ) status = models.IntegerField(choices=grade_list, default=1, verbose_name='Interview results') publishDate = models.DateTimeField(max_length=20, default=timezone.now, verbose_name='Submission time') def __str__(self): return self.name class Meta: verbose_name = 'resume' verbose_name_plural = 'resume' ordering = ('-status', '-publishDate')
Most fields in the above model use the text CharField, which has been highlighted in the previous chapter. The remaining fields are described below:
- sex: gender. Although the text CharField is still used in this field, referring to the effect shown in Figure 8-2, it can be found that the final presentation form of this field in the front end is in the form of drop-down menu, so it is necessary to convert and display. Since this chapter uses Django's model form to receive user input information, its corresponding display mode will be controlled in the form part. In fact, the field is still stored in the database in the form of text;
- Email: email. Django has a special management mechanism for mailbox fields, and the corresponding model form fields are also used for mailbox format verification. Here, you only need to use the EmailField field provided by Django;
- Birth: date of birth. This field uses DateField. Compared with DateTimeField, DateField only contains year, month and day information. In order to unify the output format, the format of the string specified by the default attribute is set here. The datetime.strftime function is used to convert the time of the current day into a format similar to "1989-04-12";
- Experience: study or work experience. Because there are many contents in this field, the TextField long text is used for declaration;
- Photo: personal photo. This field is declared with ImageField and uploaded by parameter_ To upload the image uploaded by the user to / media / contact / recruit /% Y% m_% D folder. % Y% m_% D refers to the date when the user uploaded the photos. In this way, the photos uploaded by the user every day can be stored in the same folder according to the date, which is convenient for the administrator to view and manage;
- Status: interview results. This field is declared by IntegerField and operated by the administrator through the background management system. It is used to indicate the status of the current resume, and its parameter choices points to grade_list, which is presented in the form of single choice drop-down menu in the background management system;
In addition to the above fields, you need to pay extra attention to the sorting attribute in the meta information class. This attribute is sorted by field combination. The unapproved resume is ranked at the top, followed by the passed resume, and the failed resume is ranked at the bottom. In each category, secondary sorting is carried out in chronological order. After creating the model, enter the following commands in the terminal to complete database synchronization:
python manage.py makemigrations python manage.py migrate
In this example, the user submits more data through the form. If each field uploaded by the user is manually checked one by one and the data is extracted, it will undoubtedly reduce the development efficiency and add a large number of redundant codes with repeated functions. The model form can be used as an intermediate converter to directly connect the data input by the front-end users and connect with the back-end database. A lot of verification and data extraction can be directly completed by the model form. In a sense, the model form can be regarded as a format customizer of the model, which can customize the format and verification method of each field in the model.
Let's start to create the corresponding model form for the Resume model created earlier. Create a new Python file named forms.py under contactApp. The editing code is as follows:
from django import forms from .models import Resume class ResumeForm(forms.ModelForm): class Meta: model = Resume fields = ('name', 'sex', 'personID', 'email', 'birth', 'edu', 'school', 'major', 'experience', 'position', 'photo') sex_list = ( ('male', 'male'), ('female', 'female'), ) edu_list = ( ('junior college', 'junior college'), ('undergraduate', 'undergraduate'), ('master', 'master'), ('doctor', 'doctor'), ('other', 'other'), ) widgets = { 'sex': forms.Select(choices=sex_list), 'edu': forms.Select(choices=edu_list), 'photo': forms.FileInput(), }
- First, import the forms class from Django to use the form component. The newly created model form class ResumeForm inherits from forms.ModelForm, indicating that the form is a model form;
- The model form is customized through the Meta information class Meta. The model attribute points to the specific model that needs customization. The fields attribute is used to indicate the specific fields to be customized;
- Since two fields in the model are displayed in the form of a single menu, you need to set the option sex for these two fields_ List and edu_list;
- The last attribute widgets is used to control the specific presentation form of each form field in the front end. By default, the CharField field field in the model corresponds to the input text box in HTML, and the front end form of other fields is set in widgets;
- The two radio drop-down menus sex and edu are customized by forms.Select, and the options can be set by binding the choices parameter;
- The image field adopts the file input form forms.FileInput;
After completing the construction of the model form, start to modify the recruit function in view.py as follows:
from .models import Ad from .forms import ResumeForm def recruit(request): AdList = Ad.objects.all().order_by('-publishDate') if request.method == 'POST': resumeForm = ResumeForm(data=request.POST, files=request.FILES) if resumeForm.is_valid(): resumeForm.save() return render(request, 'success.html', { 'active_menu': 'contactus', 'sub_menu': 'recruit', }) else: resumeForm = ResumeForm() return render( request, 'recruit.html', { 'active_menu': 'contactus', 'sub_menu': 'recruit', 'AdList': AdList, 'resumeForm': resumeForm, })
- In the recruit function, when the request is submitted in the form of POST, a form variable resumeForm is created through the form class constructor with parameters. The parameter data is used to obtain the corresponding data from request.POST, and files is used to receive the corresponding files (here refers to the photos uploaded by the user);
- Next, we use is_ The valid () function is used to verify whether the format of each field of the form meets the requirements. If yes, save the data through the following resumeForm.save() statement, and return the success page to the front end. If it is not in the submitted state, create a template form variable without parameters through ResumeForm(), and then return the variable to the front-end display;
Through the above code, it can be found that using Django's model form class can automatically check each field of the model, which can greatly simplify the code. Finally, start rendering the model form. Because the form components rendered by the native model form are not beautiful enough, we use the form components provided by Bootstrap. In order to use the Bootstrap form component and take advantage of the automatic rendering function of the model form, you need to use an additional third-party application Django widget tweets, which allows you to add style classes and attributes to the model form component using a specific template tag language in the front end. First download and install the application, and execute the following commands in the terminal to complete the installation:
pip install django-widget-tweaks
Then open the configuration file settings.py in installed_ Add an app to the apps field:
INSTALLED_APPS = [ ...Other applications... 'widget_tweaks', # Add custom rendering application for model form components ]
In order to use the application in the front-end template, you need to add a reference to the header of the template file recruit.html, which is specifically implemented by the tag statement {% load widget_tweets%}. Following the recruitment information module published in the previous section, the resume information upload function is written in recruit.html. The detailed code is as follows:
<div class="panel panel-default"> <div class="panel-heading"> Please fill in your resume </div> <div class="panel-body"> <div class="row"> <form action="." name="resumeForm" class="form-horizontal" method="post" role="form" enctype="multipart/form-data"> {% csrf_token %} <!-- left --> <div class="col-md-6"> <div class="form-group"> <label class="col-sm-3 control-label">full name:</label> <div class="col-sm-9"> {{resumeForm.name|add_class:"form-control"|attr:"placeholder=Please fill in your name"}} </div> </div> <div class="form-group"> <label class="col-sm-3 control-label">ID number:</label> <div class="col-sm-9"> {{resumeForm.personID|add_class:"form-control"}} </div> </div> <div class="form-group"> <label class="col-sm-3 control-label">Gender:</label> <div class="col-sm-9"> {{resumeForm.sex|add_class:"form-control"}} </div> </div> <div class="form-group"> <label class="col-sm-3 control-label">date of birth:</label> <div class="col-sm-9"> {{resumeForm.birth|add_class:"form-control"}} </div> </div> <div class="form-group"> <label class="col-sm-3 control-label">Email:</label> <div class="col-sm-9"> {{resumeForm.email|add_class:"form-control"}} </div> </div> <div class="form-group"> <label class="col-sm-3 control-label">education:</label> <div class="col-sm-9"> {{resumeForm.edu|add_class:"form-control"}} </div> </div> <div class="form-group"> <label class="col-sm-3 control-label">Graduation school:</label> <div class="col-sm-9"> {{resumeForm.school|add_class:"form-control"}} </div> </div> <div class="form-group"> <label class="col-sm-3 control-label">Major:</label> <div class="col-sm-9"> {{resumeForm.major|add_class:"form-control"}} </div> </div> <div class="form-group"> <label class="col-sm-3 control-label">Applied position:</label> <div class="col-sm-9"> {{resumeForm.position|add_class:"form-control"}} </div> </div> </div> <!-- right --> <div class="col-md-6"> <div class="form-group"> <div class="col-sm-12" style="text-align:center"> <img id="profileshow" style="width:120px" src="{% static 'img/sample.png' %}"> </div> <label class="col-sm-5 control-label">Upload certificate photos:</label> {{resumeForm.photo}} </div> <div class="form-group"> <label class="col-sm-12 control-label">Study or work experience:</label> <div class="col-sm-12"> {{resumeForm.experience|add_class:"form-control"}} </div> </div> </div> <div class="col-md-12"> <center><input type="submit" class="btn btn-primary" value="Submit" /></center> </div> </form> </div> </div> </div>
- Overall layout style: the panel component panel provided by Bootstrap is used for layout. The style adopts the default style panel default, which is divided into header and main body. The header displays the form theme and the main body displays each form control;
- Form structure: the basic form is as follows:
<form action="." name="resumeForm" method="post" class="form-horizontal" role="form" enctype="multipart/form-data"> ...Individual form controls... </form>
The action parameter in the above form is used to point to the web address of the form submission, where "." represents the current web address. Method indicates the submission form. The form submission method is generally post. Class = "form horizontal" indicates that the controls in the current form are arranged in rows. Enctype = "multipart / form data" combined with post can enable the background to obtain the file (picture) information uploaded by the user in request.FILES. The following explains how to render each HTML form element through the Django form:
- Model form component rendering: the model form component can be rendered directly through the passed in template form variable resumeForm and through the additional filter tag add_class, and add attributes through attr;
- Use and rendering of date: in order to facilitate users to input date information, this book uses an additional date component laydate.js to realize this function (official download website: https://www.layui.com/laydate/ ); Place the downloaded laydate.js component package in the static/js folder of the project (the component package can also be obtained from the supporting resources of the book), and then reference it in recruit.html:
<script src="{% static 'js/layDate-v5.0.9/laydate.js' %}"></script>
In order to use the date component function normally, you need to add additional js code to call:
<script> laydate.render({ elem: '#id_birth' }); </script>
Here, the render function of the laydate component is called, where elem is used to specify the component to be bound and bound by ID number. It should be noted that due to the model form, the ID number will be automatically generated for each component in the process of component rendering in the form of "id_" before the model field name.
- Photo upload: in order to display the photo thumbnail after the user selects the photo, additional js code needs to be added to control the picture switching of < img > tag, which is mainly realized by responding to the change event of the button. The specific code is as follows:
<script> $(function () { $('#id_photo').on('change', function () { var r = new FileReader(); f = document.getElementById('id_photo').files[0]; r.readAsDataURL(f); r.onload = function (e) { document.getElementById('profileshow').src = this.result; }; }); }); </script>
Finally, you need to create a success page success.html to prompt after the submission is successful. The message prompt box component alert provided by Bootstrap is mainly used here. The complete code is as follows:
{% extends "base.html" %} {% load static %} {% block title %} Talent recruitment {% endblock %} {% block content %} <!-- Main content --> <div class="container"> <div class="row"> <div class="alert alert-success"> <strong>success!</strong> The resume information has been uploaded successfully. The preliminary test results will be sent to you by email. </div> </div> </div> {% endblock %}
So far, the development of user resume information upload module has been completed. Export the model to the background management system in the admin.py file, and add the following code:
from .models import Resume admin.site.register(Resume)
Start the project, input and submit the complete resume information on the join Hengda page, and then open the background management system. The administrator can view the resume information uploaded by the user. The final effect is shown in the figure below:
It should be noted here that the photos uploaded by users in the background management system are provided in the form of path string url, not in the form of thumbnail, which is not intuitive for administrators. They need to find and view the pictures locally according to the path.
The following describes a method of displaying a list in a customized background management system. Specifically, the display list form of the model can be set through the admin file. In the admin.py file, the registration of model Resume is realized through admin.site.register(Resume), that is, the default registration method is adopted, and the display form of model fields is not set. Therefore, in order to effectively browse the Resume information uploaded by users, it is necessary to customize each field. The code is as follows:
from django.utils.safestring import mark_safe from .models import Resume class ResumeAdmin(admin.ModelAdmin): list_display = ('name', 'status', 'personID', 'birth', 'edu', 'school', 'major', 'position', 'image_data') def image_data(self, obj): return mark_safe(u'<img src="%s" width="120px" />' % obj.photo.url) image_data.short_description = u'Personal photos' admin.site.register(Resume, ResumeAdmin)
- Escape: first introduce make_ The safe escape function is used to escape HTML language keywords and convert HTML codes into HTML entities;
- Model manager: in order to customize the output of the model, you can use the model manager provided by Django to customize the output of the model. The model manager is created by inheriting the class admin.ModelAdmin, where list_ The display attribute lists the model fields that need to be displayed in the background management system. The photo field is not listed here, but another variable image is used_ data. Through function image_data assigns the url of photo to HTML and converts it through escape characters, so as to make the final rendered image_data can be displayed in thumbnail form;
- Binding model and model manager: bind and register the model with the model manager through the admin.site.register function;
Open the background management system, and the final presentation is shown in the following figure:
5.2.3 use of signal trigger
In the previous section, recruiters can view the resume information uploaded by candidates through the background management system of the enterprise portal website. After the recruiter has browsed a resume and decided to hire, the recruiter can change the status field to "passed". While performing field modification, the background management system needs to do some additional processing operations, such as sending employment notice e-mail to candidates. These operations need to capture and judge the recruiter's actions, that is, additional operations need to be triggered only when the recruiter changes the status field in the resume from unapproved to passed or from unapproved to failed. This section describes how to use Django's signaling mechanism to achieve this trigger effect.
The function of Django signal trigger is similar to callback function, which is used to add event monitoring and triggering mechanism for the project. Among them, the flexible use of its built-in model signals can monitor the changes of most model objects, and there is no need to modify the code of the original model. The following is developed according to the actual needs.
Edit the models.py file and add the following code
from django.db.models.signals import post_init,post_save from django.dispatch import receiver @receiver(post_init, sender=Resume) def before_save_resume(sender, instance, **kwargs): instance.__original_status = instance.status @receiver(post_save, sender=Resume) def post_save_resume(sender, instance, **kwargs): print(instance.__original_status) print(instance.status)
- Firstly, the model signal post of Django is introduced_ Init and post_save, where post_init indicates that the signal is triggered before the administrator clicks the Save button, post_save means that the signal is triggered after clicking the Save button;
- The signal is received by decorator @ receiver, in which the first parameter is the signal type and the second parameter is the model class to be monitored;
- Corresponding to two different signals, two different functions are used to respond, in which the instance parameter is the incoming model variable. Before saving, record the current status in__ original_ In the status variable, output the values of the variables before and after saving to view the changes;
When the administrator changes the status in the resume from unapproved to passed, you can view the console output at this time. The console outputs "1" and "2" respectively, as shown in the following figure:
This indicates that the status change of the administrator to status can be effectively monitored. Here, we temporarily use the form of console output status to view the trigger effect. The specific trigger content will be introduced below.
5.3 sending mail
Through the previous development and learning, a simple interactive module of recruitment and application has been built. Here are the basic processes:
(1) Recruiters publish recruitment information in the background and display it in the front end through the database;
(2) Candidates browse recruitment information and fill in resumes to apply. The application information is directly associated with the database in the form of model forms, and the format of each field is automatically checked;
(3) Recruiters browse the resume information through the background management system and touch the trigger for additional operations when changing the status;
For step (3), the previous section only implements the basic console printing function, that is, when the recruiter modifies the resume status, the key information is output in the background. In fact, we hope that whether the recruiter changes the resume status from "unapproved" to "passed" or from "unapproved" to "failed", After modification, the initial test results can be automatically sent to the candidate's mailbox without additional email from the recruiter. In order to realize the function of automatically sending mail, you need to use the corresponding mailbox function in Django. This section details how to send mail through Django.
In order to use Django's mailbox service, you need to set the mailbox server information in advance. In essence, the Web application built through Django is only a shell, which is only responsible for editing the mail content, while the actual mail sending and other functions still rely on a third-party mailbox server (such as QQ mailbox or Sina mailbox). The following takes QQ mailbox as an example to illustrate the specific operation process.
(1) qq mailbox settings
First enter the QQ mailbox, click the "setting" button at the top, and then click "account" in mailbox setting to enter the account information editing interface, as shown in the following figure.
Then scroll down to find the "open service" panel and select Open POP/SMTP service, as shown in the following figure:
In the process of opening the service, it needs to be verified by SMS. After verification, an authorization code will be obtained, saved and used later.
(2) django configuration
The Django framework comes with a mailbox module, which can be used by simple configuration. Open the configuration file settings.py and add the configuration corresponding to the mailbox:
EMAIL_HOST = 'smtp.qq.com' EMAIL_PORT = 25 # Port number EMAIL_HOST_USER = 'xxxx@qq.com' # Enterprise QQ account EMAIL_HOST_PASSWORD = 'xxxxxxxxxx' # Authorization code EMAIL_USE_TLS = True
Fill in the enterprise QQ email account and the corresponding authorization code. Next, re edit the post in the models.py file_ save_ The resume function checks the current status change when saving the modification, and then sends the specified mail content according to the conditions. The specific code is as follows:
from django.core.mail import send_mail @receiver(post_save, sender=Resume) def post_save_resume(sender, instance, **kwargs): email = instance.email # Candidate email EMAIL_FROM = 'xxxxxxxx@qq.com' # Enterprise QQ email if instance.__original_status==1 and instance.status==2: email_title = 'Notice: preliminary recruitment test results of Hengda Technology' email_body = 'Congratulations on passing the initial test of this enterprise' send_status = send_mail(email_title, email_body, EMAIL_FROM, [email]) elif instance.__original_status==1 and instance.status==3: email_title = 'Notice: preliminary recruitment test results of Hengda Technology' email_body = 'Unfortunately, you failed to pass the initial test of the enterprise. Thank you for your attention' send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])
When filling in the email content, email_title means email title_ Body is the main content of the mail, and finally through send in the django.core.mail module_ The mail function completes the mail sending.
Save all the modified running items, modify the status information of the applicant's resume through the background management system, and view the mail sending status.
As shown in the figure below, you can see that the candidate's email has been successfully received:
This section mainly describes the basic methods of using QQ mailbox in Django. Please refer to the interfaces provided by various mailbox providers for the use of other mailbox servers.
5.5 data download
This section develops the data download module supported by the enterprise portal service, which corresponds to the serviceApp application in the Hengda project. The service support module includes two sub pages: data download and artificial intelligence open platform. The data download page is mainly designed to further improve the actual needs of the enterprise portal. After purchasing products, users often need to download additional instruction manuals or SDK driver packages corresponding to each product. At this time, corresponding data download functions need to be provided on the official website to facilitate users' access. This part of the content can follow the design idea of the news dynamic module when developing, show each download information in the form of a list, and provide additional download links for specific reference Sample website Interface. Through the development of this page, we need to master the method of file download in Django. Artificial intelligence open platform is the key extension of this course, which will be introduced in the last lesson.
5.5.1 create data model
In order to enable the administrator to upload and manage data files, the data can be modeled and the corresponding data class Doc can be created in the database. Open the models.py file in the serviceApp application and define the data model as follows:
from django.db import models import django.utils.timezone as timezone class Doc(models.Model): title = models.CharField(max_length=250, verbose_name='Data name') file = models.FileField(upload_to='Service/', blank=True, verbose_name='Documentation') publishDate = models.DateTimeField(max_length=20, default=timezone.now, verbose_name='Release time') def __str__(self): return self.title class Meta: ordering = ['-publishDate'] verbose_name = "data" verbose_name_plural = verbose_name
The created data model Doc contains three fields: title, file and publishDate. The file field is used to receive the data files uploaded by the administrator through the parameter upload_to enables the uploaded files to be placed under the media/Service folder.
After the above creation, use the migration command to synchronize the Doc model to the database:
python manage.py makemigrations python manage.py migrate
Next, open the admin.py file and register the Doc model in the background management system:
from django.contrib import admin from .models import Doc admin.site.register(Doc)
After saving all the modified items, start the project, log in to the background management system, find the data model, add several pieces of data, enter the file name for each data and upload the corresponding file data, as shown in the figure below. Note that the uploaded file path cannot contain Chinese.
5.5.2 development of data download list page
The development of information download list page can learn from the development method of news list. First create the templates template folder under the serviceApp application, and then create a new template file docList.html under the Templates folder. Copy all the contents of newList.html created in the previous course into docList.html, and then modify the key parts. Since the contents are basically the same, the modified part of docList.html will not be described here. For details, please refer to the supporting resource code of this course. Here, you should pay attention to the link settings of each material, as follows:
{% for doc in docList %} <div class="news-model"> <img src="{% static 'img/newsicon.gif' %}"> <a href="{% url 'serviceApp:getDoc' doc.id %}"><b>{{doc.title}}</b></a> <span>{{doc.publishDate|date:"Y-m-d"}}]</span> </div> {% endfor %}
The template variable docList passed in the template file is used to display each item of data, which is displayed iteratively one by one through the template label {% for doc in docList%}. The download link of each data item is given in the form of "data access route + file id", and the data access route {% url 'serviceApp:getDoc'%} will be set in urls.py file.
Next, modify the urls.py file and add the getDoc route, as follows:
urlpatterns = [ ...Other routes... path('getDoc/<int:id>/', views.getDoc, name='getDoc'), ]
Then open the views.py file and modify the download function, which is mainly used to obtain the data list and render the page. The specific content is basically the same as the news function in the views.py file under the newsApp application. In actual operation, you only need to copy the content in the news function and simply modify it. The specific content will not be repeated. Please refer to the supporting resource code.
This section focuses on how to write the data download function getDoc. In lesson 2, when building the enterprise portal framework, the HttpResponse returns a string to respond to the user's request. In later lessons, the render function is used to render the page and return. Whether HttpResponse or render function, in essence, the request and response of this page can be regarded as file download, that is, the user requests the specified content. After receiving the request, the server downloads the content to the browser according to the specified format, and then the browser outputs the content. Therefore, HttpResponse can be used to directly respond to the user's download behavior for the download of specific files (word documents, PDF files, compressed packages, etc.). HttpResponse uses the iterator object, stores the contents of the iterator object as a string, and then returns it to the client, while freeing memory. However, when the file is large, if you still use HttpResponse, it will be a very time-consuming and memory consuming process, and it is easy to cause the server to crash. Therefore, the general file download will not adopt this method.
Django specifically provides a StreamingHttpResponse object for file download to replace the HttpResponse object and provide the download function in the form of stream. The StreamingHttpResponse object is used to send the file stream to the browser, which is very similar to the HttpResponse object. For the file download function, using the StreamingHttpResponse object is more stable and effective.
Specifically, add a file batch read function read in the views.py file_ File, which constructs an iterator to process files in batches, and then returns the iterator as a result. The code is as follows:
def read_file(file_name, size): with open(file_name, mode='rb') as fp: while True: c = fp.read(size) if c: yield c else: break
Where file_ The name parameter is the file path, and the size parameter indicates the size of files read in batches. Next, start to write the getDoc function. The code is as follows:
from django.shortcuts import get_object_or_404 from django.http import StreamingHttpResponse import os def getDoc(request, id): doc = get_object_or_404(Doc, id=id) update_to, filename = str(doc.file).split('/') filepath = '%s/media/%s/%s' % (os.getcwd(), update_to, filename) response = StreamingHttpResponse(read_file(filepath, 512)) response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = 'attachment;filename="{}"'.format( filename) return response
- Get file: get according to the passed in file id number_ object_ or_ 404 function extracts the file from the database;
- Read file: through read_ The file function reads the file and constructs an iterator in 512 bytes. After the iterator returns, it is directly passed to the StreamingHttpResponse;
- Set file type: the above code can transfer the file on the server to the browser through file stream, but the file stream is usually displayed in the browser in the form of garbled code rather than downloaded to the hard disk. Therefore, some statements should be made for the file to write the file stream to the hard disk. During implementation, you only need to assign values to the content type and content disposition fields of the StreamingHttpResponse object;
After saving all the modifications, start the project, open the "data download" page, and click one of the data links to download the file. The effect diagram is as follows:
This concludes the lesson.