use formsets for screening questions, create views for applying to jobs

This commit is contained in:
aatish 2018-10-20 12:44:28 +05:45
parent 7b33b832fe
commit 34b77e8a4e
8 changed files with 128 additions and 13 deletions

View file

@ -1,5 +1,5 @@
from django.contrib import admin from django.contrib import admin
from .models import Job, Application, Tag, Question from .models import Job, Application, Tag, Question, Answer
admin.site.register([Job, Application, Tag, Question]) admin.site.register([Job, Application, Tag, Question, Answer])

View file

@ -2,7 +2,7 @@ from django import forms
from django.forms import inlineformset_factory from django.forms import inlineformset_factory
from dal.autocomplete import ModelSelect2Multiple from dal.autocomplete import ModelSelect2Multiple
from .models import Job, Question from .models import Job, Question, Application, Answer
class JobForm(forms.ModelForm): class JobForm(forms.ModelForm):
@ -23,8 +23,37 @@ class QuestionForm(forms.ModelForm):
} }
class ApplicationForm(forms.ModelForm):
class Meta:
model = Application
exclude = ('job', 'applicant')
class AnswerForm(forms.ModelForm):
class Meta:
model = Answer
fields = '__all__'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['text'].required = True
self.fields['question'].disabled = True
@classmethod
def inlineformset_factory(cls, extra=3):
return inlineformset_factory(
Application,
Answer,
form=cls,
min_num=extra,
max_num=extra,
validate_min=True,
can_delete=False,
can_order=False)
QuestionFormSet = inlineformset_factory( QuestionFormSet = inlineformset_factory(
Job, Question, form=QuestionForm, can_delete=False, can_order=False) Job, Question, form=QuestionForm, can_delete=False, can_order=False)
QuestionUpdateFormSet = inlineformset_factory( QuestionUpdateFormSet = inlineformset_factory(
Job, Question, form=QuestionForm, can_delete=True, can_order=False) Job, Question, form=QuestionForm, can_delete=True, can_order=False)

View file

@ -0,0 +1,23 @@
# Generated by Django 2.1.2 on 2018-10-20 06:22
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('jobs', '0002_auto_20181017_1104'),
]
operations = [
migrations.AddField(
model_name='application',
name='cover_letter',
field=models.TextField(blank=True),
),
migrations.AlterField(
model_name='question',
name='name',
field=models.TextField(verbose_name='Question Title'),
),
]

View file

@ -70,6 +70,7 @@ class Application(models.Model):
User, related_name="applications", on_delete=models.CASCADE) User, related_name="applications", on_delete=models.CASCADE)
job = models.ForeignKey( job = models.ForeignKey(
Job, related_name="applications", on_delete=models.CASCADE) Job, related_name="applications", on_delete=models.CASCADE)
cover_letter = models.TextField(blank=True)
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)

View file

@ -0,0 +1,13 @@
{% extends 'base.html' %} {% block title %}Apply to job{% endblock %} {% load crispy_forms_tags %} {% block body_content %}
<div class="row">
<div class="col-md-12">
<form method="POST" action=".">
{% csrf_token %} {{ form |crispy }}
<h4>Screening Questions</h4>
{{ answer_form |crispy }}
<input class="btn btn-primary submit" type="submit" value="Post Job" />
</form>
{{form.media}}
</div>
</div>
{% endblock %}

View file

@ -22,7 +22,7 @@
- {{question.name}} <br/> - {{question.name}} <br/>
{% endfor %} {% endfor %}
<br/> <br/>
<a href="#" class="card-link">Apply</a> <a href="{% url 'jobs:job_apply' job.pk %}" class="card-link">Apply</a>
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,17 +1,17 @@
from django.urls import path from django.urls import path
from . import views from .views import Index, JobCreate, JobList, JobDetail, ApplicationCreate
from . import autocomplete as autocomplete_views from . import autocomplete as autocomplete_views
app_name = 'jobs' app_name = 'jobs'
urlpatterns = [ urlpatterns = [
path('', views.Index.as_view(), name='index'), path('', Index.as_view(), name='index'),
path('jobs/create/', views.JobCreate.as_view(), name='create'), path('jobs/create/', JobCreate.as_view(), name='create'),
path('jobs/', views.JobList.as_view(), name='list'), path('jobs/', JobList.as_view(), name='list'),
path('jobs/<int:pk>/detail/', views.JobDetail.as_view(), name='job_detail'), path('jobs/<int:pk>/detail/', JobDetail.as_view(), name='job_detail'),
path('jobs/<int:job_pk>/apply/', ApplicationCreate.as_view(), name='job_apply'),
] ]
# autocomplete endpoints # autocomplete endpoints
urlpatterns += [ urlpatterns += [
path( path(

View file

@ -4,8 +4,8 @@ from django.views.generic import (
TemplateView, ListView, CreateView, DetailView TemplateView, ListView, CreateView, DetailView
) )
from .models import Job from .models import Job, Application, Question
from .forms import JobForm, QuestionFormSet from .forms import JobForm, QuestionFormSet, ApplicationForm, AnswerForm
class Index(TemplateView): class Index(TemplateView):
@ -59,3 +59,52 @@ class JobCreate(CreateView):
self.get_context_data( self.get_context_data(
form=form, form=form,
question_form=question_form)) question_form=question_form))
class ApplicationCreate(CreateView):
# TODO: restrict users from re-application
model = Application
form_class = ApplicationForm
success_url = reverse_lazy("jobs:list")
def get_question_queryset(self):
return Question.objects.filter(job_id=self.kwargs['job_pk']).order_by('id')
def get_answer_formset(self, *args):
questions = self.get_question_queryset()
return AnswerForm.inlineformset_factory(
extra=questions.count())(initial=[{
'question': q.id
} for q in questions], *args)
def get(self, request, *args, **kwargs):
self.object = None
form = self.get_form(self.get_form_class())
answer_form = self.get_answer_formset()
return self.render_to_response(
self.get_context_data(form=form, answer_form=answer_form))
def post(self, request, *args, **kwargs):
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
answer_form = self.get_answer_formset(self.request.POST)
if (form.is_valid() and answer_form.is_valid()):
return self.form_valid(form, answer_form)
else:
return self.form_invalid(form, answer_form)
def form_valid(self, form, answer_form):
self.object = form.save(commit=False)
self.object.applicant = self.request.user
self.object.job = Job.objects.get(id=self.kwargs['job_pk'])
self.object.save()
answer_form.instance = self.object
answer_form.save()
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form, answer_form):
return self.render_to_response(
self.get_context_data(form=form, answer_form=answer_form))